/* Generated by mockup/tools/design-bundles.cjs. Edit core.tokens.css or themes/sally.css. */
/* Canonical shared geometry. Themes may not redefine these names. */
:root {
 --text-xs: 0.75rem;
 --text-sm: 0.875rem;
 --text-base: 1rem;
 --text-lg: 1.25rem;
 --text-xl: 1.75rem;
 --space-1: 4px;
 --space-2: 8px;
 --space-3: 12px;
 --space-4: 16px;
 --space-6: 24px;
 --space-8: 32px;
 --space-12: 48px;
 --radius-control: 6px;
 --size-button: 38px;
 --weight-button: var(--weight-bold);
 --size-control-target: 44px;
 --size-header-control: var(--size-control-target);
 --size-rail-control: var(--size-control-target);
 --radius-pill: 999px;
 --motion-fast: 160ms;
 --motion-loading-delay: 250ms;   /* loading text shows only when a route takes longer than this */
 /* Line-height roles. Choose by what the text is, never by a number. */
 --leading-solid: 1;          /* numbers, icons, single-line badges */
 --leading-display: 1.15;     /* hero numbers and display titles */
 --leading-heading: 1.35;     /* titles and section headings */
 --leading-ui: 1.45;          /* buttons, labels, captions, compact UI text */
 --leading-body: 1.6;         /* card and description text */
 --leading-reading: 1.8;      /* Korean long-form reading: article body, deck, analysis */
 --weight-regular: 400;
 --weight-semibold: 600;
 --weight-bold: 700;
 --weight-display: 750;
 --figures-number: tabular-nums lining-nums;   /* number cells: closes, changes, table columns line up digit under digit */
 --radius-round: 50%;
 --stroke-thin: 1px;
 --stroke-emphasis: 2px;
 --stroke-thick: var(--stroke-emphasis);
 --stroke-focus: 3px;
 --space-0: 0;
 --space-half: 2px;
 --space-5: 20px;
 --space-10: 40px;
 --space-16: 64px;
 --space-24: 96px;
 /* Radius scale. Components choose a step; no one-off radius values. */
 --radius-xs: 4px;
 --radius-md: 8px;
 --radius-lg: 12px;
 --radius-xl: 16px;
 --radius-2xl: 24px;
 /* Radius roles. Service CSS (Wagle, Sally, tower) names a role, never a step above (validate-design.cjs
    serviceRadiusRoles): a card, panel or popover is --radius-card, a dialog --dialog-radius, a control (input, menu
    item, inline picture) --radius-control or --button-radius, a chip or round shape --radius-pill/--radius-round,
    and the corner of a chat bubble that points at its speaker --radius-tail. */
 --radius-card: var(--radius-xl);
 --radius-tail: var(--radius-xs);
 /* Chips (control-contract.css .chip): one pill for every short label in every service. */
 --size-chip: 2rem;                 /* an interactive chip's visible height; its hit area still reaches --size-control-target */
 --size-chip-sm: 1.5rem;            /* a read-only chip (a mark, a result): compact, not a target */
 --chip-radius: var(--radius-pill);
 --chip-padding-x: var(--space-3);
 --chip-padding-x-sm: var(--space-2);
 --chip-gap: var(--space-1);        /* between the parts inside one chip */
 --chip-font-size: var(--text-xs);
 --chip-weight: var(--weight-semibold);
 --chip-row-gap: calc(var(--size-control-target) - var(--size-chip));  /* wrapped chip rows: hit areas never overlap */
 /* The site footer (control-contract.css .footer): the Mandarin wordmark at one size in every service. */
 --size-footer-wordmark: 1.5rem;
 --tracking-footer-wordmark: -1.4px;
 /* Space kept clear under the fixed site header when scrolling to an anchor. */
 --scroll-offset: var(--space-24);
 /* Fixed component sizes shared by every product. */
 --size-visually-hidden: 1px;
 --size-avatar-xs: 24px;           /* a face inside a line of text: a mention, a reply-to, a small rail */
 --size-avatar-sm: 36px;
 --size-avatar-md: 40px;
 --size-avatar-lg: 4.5rem;          /* profile header on small screens */
 --size-avatar-xl: 5.5rem;          /* profile header */
 --size-account-popover: 18rem;     /* the header account menu */
 /* Icons: one scale for every inline SVG or mask icon outside the header (header icons use --size-header-icon). */
 --size-icon: 1.25rem;
 --size-icon-sm: 1rem;              /* icon inside a small text control */
 --size-badge-inline: var(--size-icon);  /* a badge picture beside a name */
 --size-checkbox: 1.25rem;
 --weight-heavy: 800;               /* wordmarks */
 --opacity-disabled: .5;            /* disabled or read-only controls */
 --opacity-dim: .55;                /* dimmed content that is not a control: a locked step, a resting loading dot */
 --motion-attention: 1.2s;          /* a one-off attention cue (an alert bell ringing twice) */
 /* Dialogs: one shape for every service dialog; the width is chosen by role. */
 --dialog-width-compact: 30rem;     /* alerts, toasts */
 --dialog-width: 42rem;             /* a conversation or a form */
 --dialog-width-wide: 46rem;        /* a profile */
 --dialog-width-workspace: 76rem;   /* a profile with its editor beside it */
 --dialog-gutter: var(--space-8);   /* space kept around a dialog on small screens */
 --dialog-max-block: 90dvh;
 --dialog-radius: var(--radius-xl);
 /* Breakpoints. Media queries cannot read custom properties, so service CSS may only use these widths
    (max-width:N, or min-width:N+1); mockup/tools/validate-design.cjs enforces it. */
 --breakpoint-narrow: 480px;
 --breakpoint-small: 600px;
 --breakpoint-compact: 700px;
 --breakpoint-medium: 800px;
 --breakpoint-wide: 1100px;
 /* Mandarin layout steps between the shared ones. Mandarin sources name a breakpoint, @media(--breakpoint-small), and
    its bundle builders write the width (design-bundles.cjs resolveMedia), so a width is changed only here. */
 --breakpoint-phablet: 540px;
 --breakpoint-compact-plus: 740px;
 --breakpoint-tablet: 900px;
 --breakpoint-large: 1000px;
 --breakpoint-menu: 1024px;        /* the site header folds its menu */
 --breakpoint-wide-plus: 1150px;
 --breakpoint-xwide: 1550px;
 --weight-medium: 500;
 --button-height: var(--size-button);
 --button-min-width: 24px;
 --button-padding-x: var(--space-3);
 --button-padding-y: var(--space-2);
 --button-radius: var(--radius-control);
 --button-font-size: var(--text-base);
 --button-font-size-small: var(--text-xs);
 --button-weight: var(--weight-button);
 --button-line-height: var(--leading-ui);
 --button-target-height: var(--size-control-target);
 /* Header icons (language, theme, alerts): one size and stroke in every service. */
 --size-header-icon: 20px;
 /* The top of every service page (2026-10-31 user: "상단 주가 나오는 거 나오고 메뉴 두께를 맞춰서 위로 튀는 듯한 느낌은
    없었으면 좋겠어"): the world market indices strip, then the site header, at the same heights in Mandarin, Wagle and
    Sally, so moving between them moves nothing. The strip holds one control row; the header is its own height. */
 --size-market-ticker: calc(var(--button-target-height) + 2 * var(--space-1) + var(--stroke-thin));
 --size-site-header: 78px;
 --market-ticker-duration: 36s;
 --market-ticker-item-width: 19rem;
 /* The strip's pulse: a brand dot that beats while every index was collected normally (closes, not a live feed). */
 --market-pulse-size: var(--space-2);
 --motion-pulse: 1.8s;
 --stroke-icon: 2;
 --button-disabled-opacity: var(--opacity-disabled);
 /* Vertical rhythm roles. Every product (channel, journal, research, Wagle, Sally) uses these, not its own numbers. */
 --gap-tight: var(--space-2);        /* label to value, caption to figure */
 --gap-paragraph: var(--space-4);    /* paragraph to paragraph in reading text (about 1em) */
 --gap-block: var(--space-6);        /* block to block, heading to its body */
 --gap-section: var(--space-12);     /* section to section */
 --inset-card: var(--space-6);       /* inside padding of cards and panels */
 --rhythm-body-leading: var(--leading-body);
 --rhythm-heading-leading: var(--leading-heading);
 --rhythm-text-gap: var(--gap-paragraph);
 --rhythm-content-gap: var(--gap-paragraph);
 --rhythm-section-gap: var(--gap-block);
 --rhythm-action-gap: var(--gap-block);
 --action-group-gap: var(--space-3);
 /* Data table: numeric comparison tables share one contract (labels start, numbers end, tabular figures). */
 --table-cell-block: var(--space-3);        /* vertical cell padding */
 --table-cell-inline: var(--space-4);       /* horizontal cell padding */
 --table-rule: var(--stroke-thin);          /* row separator thickness; colour is --border */
 --table-head-size: var(--text-xs);
 --table-head-weight: var(--weight-semibold);
 --table-head-tracking: var(--tracking-label);
 --table-label-weight: var(--weight-semibold);
 --table-number-weight: var(--weight-medium);
 --table-number-tracking: var(--tracking-normal);
 --table-max-inline: 48rem;               /* readable table width; narrower columns keep numbers near their labels */
 /* Section headings (2026-11-01, user: "B안"): a section opens with a band (a tinted strip, an accent bar at its start,
    an icon plate before the title, a family kicker above it); a rail title opens with a kind glyph (a small rounded
    square) and its count. The colours are the theme's family roles (--family-*); these are the shapes. */
 --band-padding-block: var(--space-4);
 --band-padding-inline: var(--space-5);
 --band-gap: var(--space-4);
 --band-accent-width: var(--space-1);
 --band-radius: var(--radius-lg);
 --band-plate: 2.5rem;
 --band-plate-icon: var(--size-icon);
 --band-plate-radius: var(--radius-md);
 --band-gap-after: var(--space-6);         /* band to the section's body */
 --band-copy-min: 16rem;                   /* below this the band's action wraps under the title */
 --glyph-size: 1.5rem;
 --glyph-icon: 0.875rem;
 --glyph-radius: var(--radius-xs);
 --glyph-gap: var(--space-2);
}
@media(max-width:700px),(any-pointer:coarse){:root{--size-button:var(--size-control-target);--button-min-width:var(--size-control-target)}}
@media(max-width:700px){:root{--gap-section:var(--space-8);--inset-card:var(--space-4)}}

/* Sally theme — same three layers as Mandarin.
   1. Primitive palette: the only place a color value is written.
   2. Semantic roles used by Sally screens.
   3. Component roles (buttons).
   Muted text and the accent step down slightly from the first palette so they keep 4.5:1 on every Sally surface,
   including the soft accent wash. Control borders are separate from decorative lines so buttons keep 3:1. */

/* 1. Primitive palette */
:root {
  --paper-50: #fffaf4;
  --clay-100: #f5eee6;
  --clay-150: #eee7e2;
  --clay-200: #e9ded0;
  --clay-300: #d8c9bc;
  --clay-500: #8b8279;
  --clay-650: #6d625b;
  --clay-900: #36312f;
  --clay-950: #312b28;
  --umber-900: #40352a;
  --umber-950: #3d2c16;
  --blush-100: #f2dfe5;
  --berry-650: #a24464;
  --ember-700: #8f4031;
  --moss-100: #e0eee5;
  --moss-300: #b3c9ba;
  --moss-500: #6a9d8d;
  --honey-50: #fff7db;
  --snow-0: #ffffff;
  /* Night room (the header theme switch): warm dark clay, a lighter berry, the same moss window. */
  --night-950: #1c1816;
  --night-900: #25201d;
  --night-850: #2e2825;
  --night-700: #4a413b;
  --night-400: #9a8f86;
  --night-300: #b9ada3;
  --berry-300: #e58aa8;
  --berry-900: #4a2733;
  --ember-300: #f08f73;
  --moss-800: #2b3a33;
  --moss-900: #22302a;
  --clay-850: #2a2420;
  /* Market up and down (the indices strip): the same reds and blues as Mandarin, so a rise reads the same in every service. */
  --ruby-700: #a42b42;
  --azure-700: #285cac;
  --ruby-300: #ff8c98;
  --azure-300: #8bbcff;
}

/* 2. Semantic roles and Sally geometry */
:root {
  --color-room: var(--clay-100);
  --color-paper: var(--paper-50);
  --color-ink: var(--clay-900);
  --color-muted: var(--clay-650);
  --color-line: var(--clay-300);
  --color-control-line: var(--clay-500);
  --color-accent: var(--berry-650);
  --color-accent-soft: var(--blush-100);
  --color-light: var(--snow-0);
  --color-sage: var(--moss-500);
  --color-warning: var(--ember-700);
  --color-control: var(--clay-150);
  /* Roles the shared control contract consumes (validate-design: every brand resolves them). */
  --surface: var(--color-paper);
  --text: var(--color-ink);
  --text-secondary: var(--color-muted);

  /* Sally reads in the same face as every service (2026-11-08: Pretendard Variable from the storage, local-core/src/font-kit.cjs);
     the device face while it downloads. The brand letters keep their serif (a mark, not reading text). */
  --font-body: "Pretendard Variable", Pretendard, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-brand: Georgia,serif;
  --sally-text-bubble: 1.125rem;
  --sally-text-title: 1.6rem;
  --text-heading: clamp(1.8rem,3vw,3rem);
  --text-brand: 2.6rem;
  --text-brand-mobile: 2rem;
  --weight-normal: 400;
  --sally-weight-brand: 650;
  --leading: var(--leading-body);
  --leading-title: var(--leading-heading);
  --tracking: .1em;

  --outline: var(--stroke-focus);
  --offset: var(--stroke-focus);
  --sally-shadow-dialog: 0 24px 90px color-mix(in srgb, var(--umber-900) 21%, transparent);
  --shadow-bubble: 0 8px 28px color-mix(in srgb, var(--umber-950) 6%, transparent);

  --room-width: 1440px;
  --color-up: var(--ruby-700);
  --color-down: var(--azure-700);
  --scene-width: 58%;
  --talk-width: 42%;
  --room-min: 540px;
  --scene-max: 760px;
  --portrait-width: 90%;
  --portrait-top: var(--space-16);
  --portrait-max: 800px;
  --welcome-top: clamp(4rem,10vw,9rem);
  --control-height: var(--size-control-target);
  --input-min: 70px;
  --input-max: 180px;
  --album-width: 640px;
  --album-height: 82dvh;
  --bubble-width: 94%;
  --scene-mobile: 280px;
  --portrait-mobile-width: 80%;

  --motion-slow: 8s;
  --motion-ease: ease-in-out;
  --breath-scale: 1.015;
  --motion-photo: 1.2s;
  /* Sally is thinking (2026-10-30): the hearts that pulse while a reply is on its way. */
  --sally-heart: var(--berry-650);
  --motion-heart: 1.2s;
  --motion-heart-step: 210ms;
  --scene-gradient: radial-gradient(ellipse at 42% 32%, var(--moss-100) 0%, var(--moss-300) 40%, var(--clay-200) 76%);
  --scene-fade: linear-gradient(to bottom, transparent 70%, var(--color-room) 100%);
  --light-gradient: linear-gradient(120deg, color-mix(in srgb, var(--honey-50) 50%, transparent), transparent 60%);
  --backdrop: color-mix(in srgb, var(--clay-950) 40%, transparent);
  --z-scene: 0;
  --z-content: 1;
  --z-header: 2;
  --clip-hidden: rect(0,0,0,0);
  --hidden-size: var(--size-visually-hidden);
}

/* 2b. Night room: the same roles over the night palette. Sally's light room stays the default (:root). */
:root[data-theme="dark"] {
  --sally-heart: var(--berry-300);
  --color-room: var(--night-950);
  --color-paper: var(--night-900);
  --color-ink: var(--clay-100);
  --color-muted: var(--night-300);
  --color-line: var(--night-700);
  --color-control-line: var(--night-400);
  --color-accent: var(--berry-300);
  --color-accent-soft: var(--berry-900);
  --color-light: var(--night-950);
  --color-warning: var(--ember-300);
  --color-control: var(--night-850);
  --color-up: var(--ruby-300);
  --color-down: var(--azure-300);
  --scene-gradient: radial-gradient(ellipse at 42% 32%, var(--moss-800) 0%, var(--moss-900) 40%, var(--clay-850) 76%);
  --light-gradient: linear-gradient(120deg, color-mix(in srgb, var(--honey-50) 8%, transparent), transparent 60%);
  --backdrop: color-mix(in srgb, var(--night-950) 70%, transparent);
  color-scheme: dark;
}

/* 3. Component roles */
:root{--button-bg:var(--color-control);--button-fg:var(--color-ink);--button-border:var(--color-control-line);--button-hover-bg:var(--color-accent-soft);--button-primary-bg:var(--color-accent);--button-primary-fg:var(--color-light);--button-primary-hover-bg:var(--color-ink);--button-focus:var(--color-accent);--utility-fg:var(--color-muted);--utility-hover-fg:var(--color-ink);--utility-count-bg:var(--color-accent);--utility-count-fg:var(--color-light)}
/* Account menu roles (control-contract.css .account-*): the header portrait button and its menu. */
:root{--menu-bg:var(--color-paper);--menu-fg:var(--color-ink);--menu-muted-fg:var(--color-muted);--menu-border:var(--color-line);--menu-raised-bg:var(--color-control);--menu-shadow:var(--sally-shadow-dialog);--menu-accent-fg:var(--color-accent);--menu-z:var(--z-header);--menu-max-height:calc(100dvh - var(--size-site-header) - var(--space-4))}
:root{--chip-fg:var(--color-ink);--chip-muted-fg:var(--color-muted);--chip-bg:transparent;--chip-border:var(--color-line);--chip-hover-bg:var(--color-accent-soft);--chip-selected-fg:var(--color-ink);--chip-selected-bg:var(--color-accent-soft);--chip-selected-border:var(--color-accent);--chip-up-fg:var(--color-ink);--chip-down-fg:var(--color-ink);--chip-brand-fg:var(--color-accent);--chip-brand-bg:var(--color-accent-soft);--chip-brand-border:var(--color-accent-soft);--chip-media-fg:var(--paper-50);--chip-media-bg:color-mix(in srgb,var(--night-900) 73%,transparent)}
/* Section headings (control-contract.css .band-heading, .kind-title, 2026-11-01): Sally is one family, its accent; up and down
   keep Sally's own up/down. Nothing in Sally draws them yet; these make the shared piece usable here as it is. */
:root{--chart-accent:var(--color-accent);--chart-quiet:var(--color-muted);--chart-band:var(--color-accent-soft);--chart-band-edge:var(--color-control-line);--chart-rule:var(--color-line);--heading-ink:var(--color-ink);--heading-muted:var(--color-muted);--heading-hover:var(--color-accent);--heading-title-size:var(--text-lg);--heading-title-size-compact:var(--text-base);--heading-rail-size:var(--text-base);--heading-kicker-tracking:var(--tracking);--family-market:var(--color-accent);--family-context:var(--color-accent);--family-companies:var(--color-accent);--family-journal:var(--color-accent);--family-market-band:var(--color-accent-soft);--family-context-band:var(--color-accent-soft);--family-companies-band:var(--color-accent-soft);--family-journal-band:var(--color-accent-soft);--on-family:var(--color-light);--glyph-up:var(--color-up);--glyph-down:var(--color-down);--glyph-ranking:var(--color-accent);--glyph-warning:var(--color-warning);--glyph-filings:var(--color-accent);--glyph-ai:var(--color-accent);--glyph-context:var(--color-accent);--glyph-layer:var(--color-accent);--glyph-followup:var(--color-accent);--glyph-wash:16%}
:root{--avatar-bg:var(--color-accent-soft);--avatar-fg:var(--color-accent)}
/* The market indices strip (control-contract.css .market-ticker): paper over the room, as Mandarin's raised surface. */
:root{--ticker-bg:var(--color-paper);--ticker-border:var(--color-line);--ticker-fg:var(--color-ink);--ticker-secondary-fg:var(--color-muted);--ticker-muted-fg:var(--color-muted);--ticker-hover-bg:var(--color-accent-soft);--ticker-focus:var(--color-accent);--ticker-pulse:var(--color-accent);--ticker-pulse-idle:var(--color-muted);--ticker-up-fg:var(--color-up);--ticker-down-fg:var(--color-down);--ticker-number-font:var(--font-body)}
/* Site footer roles (control-contract.css .footer): its rule, text, wordmark, accent, face and width. */
:root{--footer-width:var(--room-width);--footer-line:var(--color-line);--footer-text:var(--color-muted);--footer-strong:var(--color-ink);--footer-accent:var(--color-accent);--footer-wordmark-font:var(--font-body)}

/* Shared control geometry. Brand colors are supplied by each theme. */
.action-group{display:flex;flex-wrap:wrap;align-items:center;gap:var(--action-group-gap)}
.action-group>.button{display:inline-flex;align-items:center;justify-content:center;text-decoration:none}
:is(button,.button,.file-button){
 box-sizing:border-box;min-height:var(--button-height);min-width:var(--button-min-width);
 padding:var(--button-padding-y) var(--button-padding-x);border-radius:var(--button-radius);
 font-size:var(--button-font-size);font-weight:var(--button-weight);line-height:var(--button-line-height);
 border:var(--stroke-thin) solid var(--button-border);background:var(--button-bg);color:var(--button-fg);
 cursor:pointer;transition:background var(--motion-fast),color var(--motion-fast),border-color var(--motion-fast);
}
:is(button,.button,.file-button):hover{background:var(--button-hover-bg)}
:is(button,.button,.file-button):focus-visible{outline:var(--stroke-focus) solid var(--button-focus);outline-offset:var(--space-1)}
:is(button,.button):disabled{opacity:var(--button-disabled-opacity);cursor:default}
:is(button,.button).primary,.send{background:var(--button-primary-bg);border-color:var(--button-primary-bg);color:var(--button-primary-fg)}
:is(button,.button).primary:hover,.send:hover{background:var(--button-primary-hover-bg)}
@media(prefers-reduced-motion:reduce){:is(button,.button,.file-button){transition:none}}
/* Chips: one pill component for every short label in every service: a company mention, a prediction and its result,
   a choice, a filter, a voice or specialty mark, a status. Something that acts (send, continue, open) is a .button,
   not a chip. The rule, kept by validate-design.cjs serviceChipContract:
   1. Size follows what the chip does, never where it sits. An interactive chip (a, button, summary, label) shows
      --size-chip and its hit area still reaches --size-control-target (WCAG 2.5.5) through an invisible ::after, so a
      compact chip is a full touch target; rows of interactive chips wrap with --chip-row-gap so targets never overlap.
      Any other element is a read-only chip: --size-chip-sm, compact, not a target.
   2. Variants are attributes, never new geometry: selected is aria-pressed="true", aria-current or
      data-state="selected"; data-tone="up|down|brand" colours the label (neutral is the default); <small> inside is
      secondary text. A service may place a chip (margin, alignment, order) but never sizes, pads, rounds or retypes it.
   3. Each theme supplies only the --chip-* colour roles. :where() keeps every rule at one class, so a screen's own
      later rule for .chip still wins the cascade. */
.chip{box-sizing:border-box;display:inline-flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:var(--chip-gap);max-inline-size:100%;min-block-size:var(--size-chip-sm);padding:0 var(--chip-padding-x-sm);border:var(--stroke-thin) solid var(--chip-border);border-radius:var(--chip-radius);background:var(--chip-bg);color:var(--chip-fg);font-size:var(--chip-font-size);font-weight:var(--chip-weight);line-height:var(--leading-ui);text-decoration:none;cursor:default}
.chip:where(a,button,summary,label){position:relative;min-block-size:var(--size-chip);padding-inline:var(--chip-padding-x);cursor:pointer;transition:background var(--motion-fast),color var(--motion-fast),border-color var(--motion-fast)}
.chip:where(a,button,summary,label)::after{content:"";position:absolute;inset-inline:0;inset-block:min(0%,calc((100% - var(--size-control-target))/2))}
.chip:where(a,button,summary,label):hover{background:var(--chip-hover-bg)}
.chip:focus-visible{outline:var(--stroke-focus) solid var(--button-focus);outline-offset:var(--space-1)}
.chip:disabled{opacity:var(--button-disabled-opacity);cursor:default}
.chip:where([aria-pressed="true"],[aria-current]:not([aria-current="false"]),[data-state="selected"]){border-color:var(--chip-selected-border);background:var(--chip-selected-bg);color:var(--chip-selected-fg)}
.chip:where([data-tone="up"]){color:var(--chip-up-fg)}
.chip:where([data-tone="down"]){color:var(--chip-down-fg)}
.chip:where([data-tone="brand"]){border-color:var(--chip-brand-border);background:var(--chip-brand-bg);color:var(--chip-brand-fg)}
/* A chip that sits on a picture (a video's length on its thumbnail): its own dark plate and light letters, readable on any colour
   under it (2026-11-13: the home's 만다린버스TV rail, a white thumbnail under the page's see-through chip). */
.chip:where([data-tone="media"]){border-color:transparent;background:var(--chip-media-bg);color:var(--chip-media-fg)}
.chip small{color:var(--chip-muted-fg)}
.chip[hidden]{display:none}
@media(prefers-reduced-motion:reduce){.chip{transition:none}}
/* Header utilities (language, theme, alerts) in every service: a quiet icon control with no box or fill; the brand
   color marks only an unread count. One definition, so Mandarin, Wagle, Sally and tower headers match; each theme
   supplies only the --utility-* colour roles. */
.utility-switch{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);height:var(--button-target-height);min-height:var(--button-target-height);min-width:var(--button-target-height);padding:0;border:0;border-radius:var(--button-radius);background:transparent;color:var(--utility-fg);font-size:var(--button-font-size-small);font-weight:var(--button-weight);white-space:nowrap}
.utility-switch:hover,.utility-switch:focus-visible{background:transparent;color:var(--utility-hover-fg)}
.utility-switch svg{width:var(--size-header-icon);height:var(--size-header-icon);fill:none;stroke:currentColor;stroke-width:var(--stroke-icon);stroke-linecap:round;stroke-linejoin:round}
.theme-switch{width:var(--button-target-height);padding:0}
.theme-switch .theme-moon,.theme-switch[aria-pressed=true] .theme-sun{display:none}
.theme-switch[aria-pressed=true] .theme-moon{display:block}
.utility-count{position:absolute;inset-block-start:var(--space-1);inset-inline-end:var(--space-1);min-inline-size:var(--space-4);padding:0 var(--space-1);border-radius:var(--radius-pill);background:var(--utility-count-bg);color:var(--utility-count-fg);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:var(--leading-solid);padding-block:var(--space-1);text-align:center}
.utility-count:empty{display:none}
/* Header right side, the same in every service and in this order: language, theme, alerts bell, account. A guest
   sees the sign-in button; a member sees the portrait button that opens the account menu (identity, my page,
   service items, sign out, policies). One definition, so Mandarin, Wagle and Sally headers match; each theme supplies
   only the --menu-* roles: colours, the layer (--menu-z) and --menu-max-height (how far below its own header the
   menu may reach). */
.header-utilities{display:flex;align-items:center;gap:var(--space-3)}
.account-controls{position:relative;flex-shrink:0;margin-left:var(--space-3)}
.account-controls [hidden]{display:none!important}
.account-signin{white-space:nowrap}
.account-trigger{display:grid;place-items:center;padding:var(--space-1);width:var(--button-target-height);height:var(--button-target-height);border:var(--stroke-thin) solid transparent;border-radius:var(--radius-control);background:transparent;color:var(--menu-fg)}
.account-trigger:hover,.account-trigger[aria-expanded=true]{background:var(--menu-raised-bg);border-color:var(--menu-border)}
/* The portrait slot holds the shared author avatar (author-avatar.js): sm in the trigger, md in the menu. */
.account-portrait{display:grid;place-items:center;width:100%;height:100%}
.account-popover{position:absolute;right:0;top:calc(100% + var(--space-2));z-index:var(--menu-z);width:min(var(--size-account-popover),calc(100vw - var(--space-8)));padding:var(--space-3);background:var(--menu-bg);color:var(--menu-fg);border:var(--stroke-thin) solid var(--menu-border);border-radius:var(--radius-control);box-shadow:var(--menu-shadow);max-height:var(--menu-max-height);overflow-y:auto;text-align:start}
.account-menu-identity{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-2) var(--space-4);margin-bottom:var(--space-2)}
.account-menu-identity .account-portrait{width:auto;height:auto;flex-shrink:0}
.account-menu-identity>div{min-width:0}.account-menu-identity strong{display:block;overflow-wrap:anywhere;font-size:var(--text-sm);font-weight:var(--weight-semibold);line-height:var(--leading-ui)}.account-menu-identity p{margin:var(--space-1) 0 0;font-size:var(--text-xs);line-height:var(--leading-body);color:var(--menu-muted-fg)}
.account-popover .account-menu-link,.account-popover .account-menu-signout{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--button-padding-y) var(--button-padding-x);font-size:var(--button-font-size);line-height:var(--button-line-height);font-weight:var(--weight-medium);border-radius:var(--radius-control);color:var(--menu-fg);text-decoration:none;transition:background var(--motion-fast),border-color var(--motion-fast)}
.account-popover .account-menu-link{min-height:var(--button-target-height);background:var(--menu-raised-bg);border:var(--stroke-thin) solid transparent}
.account-popover .account-menu-link+.account-menu-link{margin-top:var(--space-2)}
.account-menu-link svg{flex:none;width:var(--space-5);height:var(--space-5);color:var(--menu-muted-fg);fill:none;stroke:currentColor;stroke-width:var(--stroke-icon);stroke-linecap:round;stroke-linejoin:round}
.account-popover .account-menu-link:hover{background:var(--menu-raised-bg);border-color:var(--menu-border)}
.account-popover .account-menu-signout{justify-content:center;min-height:var(--button-height);margin-top:var(--space-2);background:transparent;border:var(--stroke-thin) solid var(--menu-border);color:var(--menu-muted-fg);font-size:var(--text-xs)}
.account-popover .account-menu-signout:hover{background:var(--menu-raised-bg);color:var(--menu-fg)}
.account-menu-policies{display:flex;justify-content:center;flex-wrap:wrap;gap:var(--space-4);margin-top:var(--space-4);padding-top:var(--space-3);border-top:var(--stroke-thin) solid var(--menu-border);font-size:var(--text-xs);line-height:var(--leading-body);color:var(--menu-muted-fg)}
.account-menu-policies a{color:inherit;text-decoration:none}.account-menu-policies a:hover{color:var(--menu-accent-fg)}
@media(prefers-reduced-motion:reduce){.account-popover :is(.account-menu-link,.account-menu-signout){transition:none}}
/* Icons outside the header: one size and stroke in every service; a context may pick --size-icon-sm. */
.ui-icon{inline-size:var(--size-icon);block-size:var(--size-icon);flex:none;fill:none;stroke:currentColor;stroke-width:var(--stroke-icon);stroke-linecap:round;stroke-linejoin:round}
/* Native select lists (2026-10-11): the open list takes the page theme. A select drawn on a transparent background let
   Windows browsers open a white list with the theme's light text (unreadable in dark mode). */
select{color-scheme:inherit}
select option,select optgroup{background-color:var(--surface);color:var(--text)}
select option:disabled{color:var(--text-secondary)}
/* The one close control (2026-10-10; shared by every service 2026-10-11): an X that turns on hover. Dialogs, drawers and panels use .close-x instead of a
   text button or their own copy of the icon rules. */
.close-x{display:grid;place-items:center;width:var(--button-target-height);min-height:var(--button-target-height);padding:0;background:transparent;border-color:transparent;color:var(--text-secondary)}
dialog .close.close-x{padding:0;min-height:var(--button-target-height)}
.close-x svg{width:var(--size-icon);height:var(--size-icon);transition:transform var(--motion-fast)}
@media(hover:hover){.close-x:hover svg{transform:rotate(90deg)}}
@media(prefers-reduced-motion:reduce){.close-x svg{transition:none}}
/* The world market indices strip above the site header (2026-10-31 user: "상단 주가 나오는 거 나오고 메뉴 두께를 맞춰서
   위로 튀는 듯한 느낌은 없었으면 좋겠어. 지금 샐리를 누르면 위로 올라가는 듯한 느낌이 들어서 리듬을 깨는 것 같다."): one strip
   in Mandarin, Wagle and Sally, --size-market-ticker tall over a --size-site-header header (core tokens), drawn by
   shared/scripts/market-ticker.js. A page holds the empty bar from its first paint, so the quotes arrive without moving
   anything. Geometry here; each theme gives the --ticker-* colours and number face. 600px is --breakpoint-small (this
   file is served unbuilt to Wagle, so the width is written out). */
.market-ticker{box-sizing:border-box;display:flex;align-items:center;gap:var(--space-3);min-width:0;min-block-size:var(--size-market-ticker);padding:var(--space-1) var(--space-6);border-bottom:var(--stroke-thin) solid var(--ticker-border);background:var(--ticker-bg);color:var(--ticker-fg);font-size:var(--text-xs)}
.market-ticker[hidden]{display:none}
.market-ticker-window{flex:1;min-width:0;overflow:hidden}
.market-ticker-track{display:flex;width:max-content;animation:market-roll var(--market-ticker-duration) linear infinite}
.market-ticker-group{display:flex;flex-shrink:0;align-items:center;min-width:100vw;justify-content:space-around}
.market-ticker-item{display:flex;align-items:center;gap:var(--space-3);min-width:var(--market-ticker-item-width);padding-inline:var(--space-6);font-family:var(--ticker-number-font);white-space:nowrap;color:inherit;text-decoration:none;font-variant-numeric:var(--figures-number)}
.market-ticker-item>span{color:var(--ticker-secondary-fg)}
.market-ticker-item small{color:var(--ticker-muted-fg);font-size:var(--text-xs)}
.market-ticker .market-up{color:var(--ticker-up-fg)}
.market-ticker .market-down{color:var(--ticker-down-fg)}
.market-ticker-item:focus-visible{outline:var(--stroke-focus) solid var(--ticker-focus);outline-offset:calc(-1 * var(--space-1))}
.market-ticker-toggle{display:inline-flex;align-items:center;justify-content:center;flex:none;min-width:var(--button-target-height);min-height:var(--button-target-height);border:0;border-radius:var(--button-radius);background:transparent;color:var(--ticker-secondary-fg);cursor:pointer}
.market-ticker-toggle:hover{background:var(--ticker-hover-bg)}
.market-ticker-pulse{position:relative;flex:none;inline-size:var(--market-pulse-size);block-size:var(--market-pulse-size);border-radius:50%;background:var(--ticker-pulse)}
.market-ticker-pulse::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--ticker-pulse);animation:market-pulse var(--motion-pulse) ease-out infinite}
.market-ticker-pulse[data-state=stale]{background:var(--ticker-pulse-idle)}
.market-ticker-pulse[data-state=stale]::after{content:none}
@keyframes market-pulse{0%{transform:scale(1);opacity:.75}70%,100%{transform:scale(2.6);opacity:0}}
.market-ticker-toggle svg{width:var(--size-header-icon);height:var(--size-header-icon);pointer-events:none}
.market-ticker[data-paused=true] .market-ticker-track,.market-ticker-window:focus-within .market-ticker-track{animation-play-state:paused}
@media(hover:hover) and (pointer:fine){.market-ticker-window:hover .market-ticker-track{animation-play-state:paused}}
@keyframes market-roll{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.market-ticker-pulse::after{content:none}.market-ticker-track{animation:none}.market-ticker-window{overflow-x:auto}.market-ticker-group[aria-hidden=true]{display:none}.market-ticker-toggle{display:none}}
@media(max-width:600px){.market-ticker{padding-inline:var(--space-3);gap:var(--space-2)}.market-ticker-item{padding-inline:var(--space-4)}}
@media print{.market-ticker{display:none}}
/* The site footer (2026-10-24 user: "푸터가 안 들어가 있는 페이지들이 있어 … 구조는 확실하게 통일하자"): one structure in
   every service — the Mandarin wordmark, the tagline, the policy links (About Mandarin, Terms, Privacy) and an optional
   note. Mandarin's app and static pages take the markup from mockup/index.html (static-header.cjs); Wagle and Sally
   write the same markup with their own copy. Geometry here; each theme gives the --footer-* colours, face and width.
   800px is --breakpoint-medium (this file is served unbuilt to Wagle, so the width is written out). */
.footer{box-sizing:border-box;max-width:var(--footer-width);margin:auto;padding:var(--space-6) var(--space-8);border-top:var(--stroke-thin) solid var(--footer-line);display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3) var(--space-6);font-size:var(--text-xs);color:var(--footer-text)}
.footer p{margin:0;font-size:var(--text-xs)}
.footer a{color:inherit;text-decoration:none}
.footer a:hover{color:var(--footer-accent)}
.footer .footer-wordmark{font-family:var(--footer-wordmark-font);font-size:var(--size-footer-wordmark);font-weight:var(--weight-bold);letter-spacing:var(--tracking-footer-wordmark);white-space:nowrap;color:var(--footer-strong)}
.footer-wordmark span{color:var(--footer-accent)}
.footer-policies{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-4);margin:0}
.footer .footer-note{margin-left:auto}
@media(max-width:800px){.footer{padding-inline:var(--space-5)}.footer .footer-note{flex-basis:100%;margin-left:0}}
/* The author avatar (2026-10-24 user: "공용 손을 하나 만들어라. 중구난방 다른 모양을 만들지 마라."): one round face for
   every author in every service — a member, a crew reporter or editor, a company guardian, a service account, Sally.
   shared/scripts/author-avatar.js (MandarinAvatar) writes the markup: <span class="avatar" data-size> with the picture
   from the one avatar map, or the initial (data-monogram) when there is no picture or it fails to load. The size is a
   token step (data-size xs|sm|md|lg|xl = --size-avatar-*), never a screen's own width; a screen may only place an avatar
   (margin, position, order). Pictures drawn on a plain ground (guardians) keep their whole figure (data-fit="contain").
   Each theme gives the --avatar-* colours. */
.avatar{--avatar-size:var(--size-avatar-sm);box-sizing:border-box;display:inline-grid;place-items:center;flex:none;inline-size:var(--avatar-size);block-size:var(--avatar-size);overflow:hidden;border-radius:var(--radius-round);background:var(--avatar-bg);color:var(--avatar-fg);font-size:var(--text-sm);font-weight:var(--weight-semibold);line-height:var(--leading-solid);vertical-align:middle;user-select:none}
.avatar[data-size="xs"]{--avatar-size:var(--size-avatar-xs);font-size:var(--text-xs)}
.avatar[data-size="md"]{--avatar-size:var(--size-avatar-md)}
.avatar[data-size="lg"]{--avatar-size:var(--size-avatar-lg);font-size:var(--text-xl)}
.avatar[data-size="xl"]{--avatar-size:var(--size-avatar-xl);font-size:var(--text-xl)}
.avatar>img{display:block;inline-size:100%;block-size:100%;object-fit:cover}
.avatar[data-fit="contain"]>img{object-fit:contain}
/* The profile-header step keeps a phone row free: xl is lg up to 700px (--breakpoint-compact; this file is served unbuilt). */
@media(max-width:700px){.avatar[data-size="xl"]{--avatar-size:var(--size-avatar-lg)}}
/* Section headings (2026-11-01, user: "B안, 니 추천대로 가자"; page-agnostic so every menu page and service can take it):
   .band-heading opens a section — its family's soft surface (data-family market|context|companies|journal → the theme's
   --family-* and --family-*-band), an accent bar at the start, an icon plate (.band-heading-plate, the family's mono mask
   icon on its accent), the kicker above the title (.band-heading-kicker: the local word spoken, the Latin tag aria-hidden),
   the title (h2), muted subtitle lines (.band-heading-sub, data-strong for the one line that says so-what) and the
   action link at the end. .kind-title opens a rail or a block inside a section: its kind glyph (.kind-glyph, a mask icon
   in a rounded square of the kind's colour, data-heading-icon), the title (h3) with its count (the shared .chip) and the
   basis line under it (.kind-title-basis). Markup from MandarinHeading (scripts/page-shell.js). Shapes: core tokens
   --band-*, --glyph-*; colours: theme roles --family-*, --on-family, --glyph-*, and the --heading-* ink and sizes (each brand's theme supplies them). */
.band-heading{display:flex;flex-wrap:wrap;align-items:center;gap:var(--band-gap);margin:0 0 var(--band-gap-after);padding:var(--band-padding-block) var(--band-padding-inline);background:var(--band-surface);border-inline-start:var(--band-accent-width) solid var(--band-accent);border-radius:var(--band-radius)}
.band-heading[data-family="market"]{--band-accent:var(--family-market);--band-surface:var(--family-market-band)}
.band-heading[data-family="context"]{--band-accent:var(--family-context);--band-surface:var(--family-context-band)}
.band-heading[data-family="companies"]{--band-accent:var(--family-companies);--band-surface:var(--family-companies-band)}
.band-heading[data-family="journal"]{--band-accent:var(--family-journal);--band-surface:var(--family-journal-band)}
/* video (2026-11-13, 만다린버스TV shorts on the home): the journal's colours, its own play mark. */
.band-heading[data-family="video"]{--band-accent:var(--family-journal);--band-surface:var(--family-journal-band)}
.band-heading-plate{flex:none;display:grid;place-items:center;width:var(--band-plate);height:var(--band-plate);border-radius:var(--band-plate-radius);background:var(--band-accent);color:var(--on-family)}
.band-heading-plate::before,.kind-glyph::before{content:"";display:block;background:currentColor;-webkit-mask:var(--heading-icon) center/contain no-repeat;mask:var(--heading-icon) center/contain no-repeat}
.band-heading-plate::before{width:var(--band-plate-icon);height:var(--band-plate-icon)}
.band-heading-copy{flex:1 1 var(--band-copy-min);min-width:0;display:grid;gap:var(--space-1)}
.band-heading-kicker{margin:0;color:var(--band-accent);font-size:var(--text-xs);font-weight:var(--weight-bold);letter-spacing:var(--heading-kicker-tracking);line-height:var(--leading-ui);text-transform:uppercase}
.band-heading :is(h1,h2,h3){margin:0;font-size:var(--heading-title-size);line-height:var(--leading-heading)}
.band-heading-sub{margin:0;color:var(--heading-muted);font-size:var(--text-sm);line-height:var(--leading-ui)}
.band-heading-sub[data-strong]{color:var(--heading-ink);font-weight:var(--weight-semibold)}
.band-heading>.text-link{flex:none;font-size:var(--text-xs)}
.kind-title{display:grid;gap:var(--space-1);min-width:0}
.kind-title :is(h2,h3,h4){display:flex;flex-wrap:wrap;align-items:center;gap:var(--glyph-gap);margin:0;font-size:var(--heading-rail-size);line-height:var(--leading-heading)}
.kind-title :is(h2,h3,h4) a{color:inherit}
.kind-title :is(h2,h3,h4) a:hover,.kind-title :is(h2,h3,h4) a:focus-visible{color:var(--heading-hover)}
.kind-title-basis{margin:0;color:var(--heading-muted);font-size:var(--text-xs);line-height:var(--leading-ui)}
.kind-glyph{flex:none;display:grid;place-items:center;width:var(--glyph-size);height:var(--glyph-size);border-radius:var(--glyph-radius);color:var(--heading-tone);background:color-mix(in srgb,var(--heading-tone) var(--glyph-wash),transparent)}
.kind-glyph::before{width:var(--glyph-icon);height:var(--glyph-icon)}
/* A chart block (2026-11-13, user: "다닥다닥 붙어있고 … 뭘 먼저 먹어야 하는지"): .chart-lead is the block's one bold sentence,
   .chart-legend the keys right above its one chart (.chart-key data-mark: accent = the point, ink = the plain mark, ring = a
   hollow mark, quiet = the neutral grey, band = the usual range), .chart-more folds the rest. Markup from MandarinHeading
   (scripts/page-shell.js). Room between blocks is spacing tokens only. */
.chart-lead{margin:var(--space-2) 0 var(--space-3);color:var(--heading-ink);font-size:var(--text-lg);font-weight:var(--weight-bold);line-height:var(--leading-heading);text-wrap:pretty}
.chart-legend{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1) var(--space-4);margin:0 0 var(--space-2);color:var(--heading-muted);font-size:var(--text-xs);line-height:var(--leading-ui)}
.chart-legend>span{display:inline-flex;align-items:center;gap:var(--space-1)}
.chart-key{flex:none;display:inline-block;width:var(--space-3);height:var(--space-3);border-radius:var(--radius-round);background:var(--heading-ink);border:var(--stroke-emphasis) solid var(--heading-ink)}
.chart-key[data-mark="accent"]{background:var(--chart-accent);border-color:var(--chart-accent)}
.chart-key[data-mark="ring"]{background:transparent;border-color:var(--chart-quiet)}
.chart-key[data-mark="quiet"]{background:var(--chart-quiet);border-color:var(--chart-quiet)}
.chart-key[data-mark="band"]{width:var(--space-4);border-radius:var(--radius-xs);background:var(--chart-band);border-color:var(--chart-band-edge)}
.chart-more{margin-block-start:var(--space-4);border-block-start:var(--stroke-thin) solid var(--chart-rule);padding-block-start:var(--space-3)}
.chart-more>summary{cursor:pointer;color:var(--heading-muted);font-size:var(--text-sm);font-weight:var(--weight-semibold)}
.chart-more>summary:hover,.chart-more>summary:focus-visible{color:var(--heading-hover)}
.chart-more[open]>summary{margin-block-end:var(--space-3)}
/* A phone keeps the band compact, the plate beside the title and the action on its own line (600px = --breakpoint-small; this file is served unbuilt). */
@media(max-width:600px){.band-heading{gap:var(--space-3);padding:var(--space-3) var(--space-4)}.band-heading-copy{flex-basis:0}.band-heading>.text-link{flex-basis:100%}.band-heading :is(h1,h2,h3){font-size:var(--heading-title-size-compact)}}
[data-heading-icon="market"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 17l5.5-5.5 4 4L21 7'/%3E%3Cpath d='M15 7h6v6'/%3E%3C/svg%3E")}
[data-heading-icon="context"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3'/%3E%3C/svg%3E");--heading-tone:var(--glyph-context)}
[data-heading-icon="companies"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 21V4.5A1.5 1.5 0 0 1 5.5 3h9A1.5 1.5 0 0 1 16 4.5V21'/%3E%3Cpath d='M16 9h2.5A1.5 1.5 0 0 1 20 10.5V21'/%3E%3Cpath d='M2.5 21h19'/%3E%3Cpath d='M8 7.5h4M8 11.5h4M8 15.5h4'/%3E%3C/svg%3E")}
[data-heading-icon="journal"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 5H8a4 4 0 0 1 4 4v11a3 3 0 0 0-3-3H2.5z'/%3E%3Cpath d='M21.5 5H16a4 4 0 0 0-4 4v11a3 3 0 0 1 3-3h6.5z'/%3E%3C/svg%3E")}
[data-heading-icon="video"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='3'/%3E%3Cpath d='M10 9.5v5l4.5-2.5z'/%3E%3C/svg%3E")}
[data-heading-icon="up"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'%3E%3Cpath d='M12 4.5l8.5 14h-17z'/%3E%3C/svg%3E");--heading-tone:var(--glyph-up)}
[data-heading-icon="down"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'%3E%3Cpath d='M12 19.5l-8.5-14h17z'/%3E%3C/svg%3E");--heading-tone:var(--glyph-down)}
[data-heading-icon="ranking"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 20V4M3 8l4-4 4 4M17 4v16M13 16l4 4 4-4'/%3E%3C/svg%3E");--heading-tone:var(--glyph-ranking)}
[data-heading-icon="warning"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v10M12 19.6v.4'/%3E%3C/svg%3E");--heading-tone:var(--glyph-warning)}
[data-heading-icon="filings"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3h8.5L19 7.5V21H6z'/%3E%3Cpath d='M14 3v5h5M9 12.5h7M9 16.5h7'/%3E%3C/svg%3E");--heading-tone:var(--glyph-filings)}
[data-heading-icon="ai"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'%3E%3Cpath d='M12 2c.9 5.4 4.6 9.1 10 10-5.4.9-9.1 4.6-10 10-.9-5.4-4.6-9.1-10-10 5.4-.9 9.1-4.6 10-10z'/%3E%3C/svg%3E");--heading-tone:var(--glyph-ai)}
[data-heading-icon="layer"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12.5c2.5-5.5 5-5.5 7.5 0s5 5.5 7.5 0c1.4-3 3-3.5 5-2'/%3E%3C/svg%3E");--heading-tone:var(--glyph-layer)}
[data-heading-icon="followup"]{--heading-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15M13.5 6l6 6-6 6'/%3E%3C/svg%3E");--heading-tone:var(--glyph-followup)}
