/* COPIED from ~/Desktop/Design System/tokens.css on 2026-10-20 by selfprint/tools/build_zds.py.
   Do not edit here — change the Design System, then re-run the script. */
/* =============================================================================
   Zigu Design System — tokens.css  (v0.2)
   Source: Figma "🚀Zigu-Design-System.Base.DesignToken.ver0.1" local styles,
           cleaned up 2026-10-11 (see docs/CLEANUP_LOG.md).

   Layers — UI code should use layer 2 (semantic) and 3 (component) only.
     1. Primitive   palette values            --gray-500, --primary-500, --red-500 …
     2. Semantic    role, theme-aware         --text-primary, --bg-subtle, --border-default …
     3. Component   per-component overrides   --button-primary-bg, --field-border …

   Theme: light by default. Dark via <html data-theme="dark">, or automatically
   from the OS unless <html data-theme="light"> is set.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------------------
     1. PRIMITIVE — color
     ------------------------------------------------------------------------ */

  /* Mono */
  --white: #FFFFFF;
  --black: #000000;

  /* Gray (bluish neutral) — the only neutral scale */
  --gray-50:  #F6F8F9;
  --gray-100: #EDEFF0;
  --gray-150: #E6E9ED;
  --gray-200: #D3D7DC;
  --gray-300: #B4BEC5;
  --gray-400: #97A4AC;
  --gray-450: #80909B;
  --gray-500: #6A7C87;
  --gray-600: #5D6D78;
  --gray-700: #4D5A61;
  --gray-800: #3C464D;
  --gray-900: #2A3237;

  /* Alpha — black-aN / white-aN = N% opacity */
  --black-a1:  rgb(0 0 0 / 0.01);
  --black-a2:  rgb(0 0 0 / 0.02);
  --black-a3:  rgb(0 0 0 / 0.03);
  --black-a5:  rgb(0 0 0 / 0.05);
  --black-a7:  rgb(0 0 0 / 0.07);
  --black-a10: rgb(0 0 0 / 0.10);
  --black-a50: rgb(0 0 0 / 0.50);
  --black-a65: rgb(0 0 0 / 0.65);
  --black-a75: rgb(0 0 0 / 0.75);
  --white-a5:  rgb(255 255 255 / 0.05);
  --white-a10: rgb(255 255 255 / 0.10);
  --white-a20: rgb(255 255 255 / 0.20);
  --white-a30: rgb(255 255 255 / 0.30);
  --white-a50: rgb(255 255 255 / 0.50);
  --white-a65: rgb(255 255 255 / 0.65);

  /* Dimmed — gray-900 overlays */
  --dimmed-30: rgb(42 50 55 / 0.30);
  --dimmed-60: rgb(42 50 55 / 0.60);
  --dimmed-90: rgb(42 50 55 / 0.90);

  /* Primary (brand blue) — with interaction states.
     focus is shown with a focus ring, not a color; drag uses press. */
  --primary-50:  #F0F7FF;  --primary-50-hover:  #E5F1FF;  --primary-50-press:  #DFEFFF;
  --primary-100: #C2E0FF;  --primary-100-hover: #B7DAFF;  --primary-100-press: #B1D7FF;
  --primary-200: #99CCF3;  --primary-200-hover: #99CCF3;  --primary-200-press: #99CCF3;
  --primary-300: #66B2FF;  --primary-300-hover: #5EAEFF;  --primary-300-press: #5AACFF;
  --primary-400: #3399FF;  --primary-400-hover: #2F96FD;  --primary-400-press: #2D94FC;
  --primary-500: #007FFF;  --primary-500-hover: #007CF9;  --primary-500-press: #007AF6;
  --primary-600: #0072E5;  --primary-600-hover: #006FE3;  --primary-600-press: #006EE2;
  --primary-700: #0059B2;  --primary-700-hover: #0057AD;  --primary-700-press: #0055AB;
  --primary-800: #004993;  --primary-800-hover: #00478F;  --primary-800-press: #00468D;
  --primary-900: #003A75;  --primary-900-hover: #003872;  --primary-900-press: #003A75;

  /* Main */
  --red-50:  #FEEBEC; --red-100: #FDD3D4; --red-200: #FBA9AB; --red-300: #F9888B; --red-400: #F96C70;
  --red-500: #F85A5E; --red-600: #EE4649; --red-700: #E73438; --red-800: #C92529; --red-900: #A61E21;
  --red-500-hover: #DE5154;

  --blue-50:  #EAF2FE; --blue-100: #D3E4FD; --blue-200: #AACBFB; --blue-300: #7FAEF8; --blue-400: #5E96F0;
  --blue-500: #357DE5; --blue-600: #2F6ECD; --blue-700: #275EB0; --blue-800: #204E91; --blue-900: #193E73;

  --navy-50:  #E6E9F5; --navy-100: #CCD2EB; --navy-200: #99A6D6; --navy-300: #667ABF; --navy-400: #33509E;
  --navy-500: #001B57; --navy-600: #00174A; --navy-700: #00133D; --navy-800: #000F30; --navy-900: #000B24;

  --yellow-50:  #FFF9E5; --yellow-100: #FFF2C9; --yellow-200: #FFE99F; --yellow-300: #FCDE74; --yellow-400: #FAD248;
  --yellow-500: #F7C954; --yellow-600: #D9A53F; --yellow-700: #B98739; --yellow-800: #966B2F; --yellow-900: #735327;
  --highlight: #FFE81D; /* system chat balloon only — was yellow300 */

  --turquoise-50:  #E8F8FA; --turquoise-100: #CFF1F4; --turquoise-200: #A3E3E8; --turquoise-300: #7FD5DC; --turquoise-400: #65C7D1;
  --turquoise-500: #5EBCCA; --turquoise-600: #51A8B0; --turquoise-700: #438C92; --turquoise-800: #366F74; --turquoise-900: #285255;

  /* Sub (200 = tint, 500 = solid) */
  --darkNavy-200:   #D3D6DA; --darkNavy-500:   #1F2940;
  --green-200:      #E9F8EE; --green-500:      #71CB9B;
  --sky-200:        #DEF3F9; --sky-500:        #58C5E3;
  --darkPurple-200: #E0DEF1; --darkPurple-500: #6258BA;
  --pink-200:       #FCE9EE; --pink-500:       #F97F90;
  --paleYellow-200: #FBF2E6; --paleYellow-500: #EABF80;
  --purple-200:     #F0E8F6; --purple-500:     #B48BD3;
  --lightGreen-200: #F1F8E7; --lightGreen-500: #BBDA85;
  --paleBlue-200:   #EDF1FB; --paleBlue-500:   #A3B7ED;
  --paleSky-200:    #E5F0F7; --paleSky-500:    #7FB2D6;

  /* Dark-mode neutrals */
  --cool-300: #CCD2D9; --cool-400: #97A4AC; --cool-500: #80909B; --cool-600: #4C5357;
  --cool-700: #2A3237; --cool-800: #282F33; --cool-900: #19191B;
  --warm-300: #8D909B; --warm-400: #4A4E52; --warm-500: #353638; --warm-600: #2F3134;
  --warm-700: #2E2F32; --warm-800: #1E1E1F; --warm-900: #1B1919;

  /* ---------------------------------------------------------------------------
     1. PRIMITIVE — typography
     ------------------------------------------------------------------------ */
  --font-sans: "Pretendard Variable", Pretendard, var(--font-emoji), -apple-system, BlinkMacSystemFont, system-ui,
               "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;   /* code blocks only (Editor) — everything else is Pretendard */
  --font-emoji: "Noto Color Emoji";   /* every emoji, everywhere (in --font-sans right after Pretendard, so only what Pretendard lacks) — SIL Open Font License 1.1: free to use, embed, ship; no credit line. Google Fonts, loaded per emoji (unicode-range) */
  --font-regular: 400;
  /* other scripts: see "Languages" after :root — each script in its own culture's type (v0.5.157) */
  --font-medium: 500;
  --font-bold: 700;
  --tracking: -0.0186em; /* every Figma text style uses ≈ -1.86% of font size */

  /* size / line-height pairs */
  --h1-size: 44px; --h1-lh: 56px;
  --h2-size: 36px; --h2-lh: 44px;
  --h3-size: 32px; --h3-lh: 40px;
  --h4-size: 28px; --h4-lh: 36px;
  --h5-size: 24px; --h5-lh: 32px;
  --h6-size: 20px; --h6-lh: 28px;
  --h7-size: 18px; --h7-lh: 24px;

  --body-3xs-size: 10px; --body-3xs-lh: 14px;
  --body-2xs-size: 11px; --body-2xs-lh: 16px;
  --body-xs-size:  12px; --body-xs-lh:  16px;
  --body-sm-size:  14px; --body-sm-lh:  20px;
  --body-md-size:  16px; --body-md-lh:  24px;
  --body-lg-size:  20px; --body-lg-lh:  32px;
  --body-xl-size:  24px; --body-xl-lh:  36px;
  --body-2xl-size: 28px; --body-2xl-lh: 40px;

  /* ---------------------------------------------------------------------------
     1. PRIMITIVE — space, radius, size, shadow
     ------------------------------------------------------------------------ */
  /* 4px grid; 2px is the only sub-grid step. Name = pixel value. */
  --space-0: 0;
  --space-2: 2px;
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-20: 20px;
  --space-24: 24px;
  --space-32: 32px;
  --space-40: 40px;
  --space-48: 48px;

  --radius-xs: 2px;    /* inputs, dropdown items, checkbox */
  --radius-sm: 4px;    /* buttons, tags, small cards */
  --radius-md: 8px;    /* modals, toasts, popovers, cards */
  --radius-lg: 16px;   /* large sheets, app toasts */
  --radius-full: 999px;

  /* control heights */
  --size-xs: 24px;
  --size-sm: 28px;
  --size-md: 36px;     /* default button / field */
  --size-lg: 40px;
  --size-xl: 52px;

  /* icon sizes (Figma <Icon> sizes) */
  --icon-xs: 12px;
  --icon-sm: 16px;
  --icon-md: 20px;
  --icon-lg: 24px;
  --icon-xl: 32px;

  --shadow-xs:   0 1px 3px 0 rgb(0 0 0 / 0.15);                                            /* type03·07·08 */
  --shadow-glow: 0 0 4px 0 rgb(0 0 0 / 0.10);                                              /* type09, switch/hover, dropdown/active */
  --shadow-sm:   0 2px 5px -1px rgb(50 50 93 / 0.25), 0 1px 3px -1px rgb(0 0 0 / 0.30);    /* type04 */
  --shadow-md:   0 8px 24px 0 rgb(0 0 0 / 0.20);                                           /* type01·02 */
  --shadow-lg:   0 50px 100px -20px rgb(50 50 93 / 0.25), 0 30px 60px -30px rgb(0 0 0 / 0.30); /* type05·06 */
  --shadow-top:  0 -10px 60px -30px rgb(0 0 0 / 0.25), 0 -26px 100px -20px rgb(50 50 93 / 0.20); /* type10, bottom sheets */
  --shadow-left: -10px 0 60px -30px rgb(0 0 0 / 0.25), -26px 0 100px -20px rgb(50 50 93 / 0.20); /* type10 turned to the left: windows that slide in from the right (v0.5.139) */
  --shadow-right: 10px 0 60px -30px rgb(0 0 0 / 0.25), 26px 0 100px -20px rgb(50 50 93 / 0.20);  /* its mirror: the same windows in a right-to-left language slide in from the left (v0.5.166) */

  /* layers (z-index). Overlays anchored in page content stay UNDER sticky bars when the page scrolls;
     an overlay opened from inside a bar lives in the bar's stacking context, so it still shows above it. */
  --z-raised: 1;        /* lifted inside content (cards on hover, stacked avatars) */
  --z-dropdown: 10;     /* menus anchored in content */
  --z-tooltip: 20;      /* tooltips anchored in content */
  --z-sticky: 100;      /* sticky / fixed app bars, side bars */
  --z-overlay: 200;     /* modal backdrop */
  --z-modal: 210;
  --z-toast: 300;

  --duration-fast: 120ms;
  --duration-base: 200ms;
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-accelerate: cubic-bezier(0.3, 0, 0.8, 0.15);   /* leaving: starts slow, speeds away (a sheet pulled down) */

  /* device safe areas — the OS draws the status bar and the home bar; components only leave their room (v0.5.95).
     They read the browser (env(), needs viewport-fit=cover). A native shell whose WebView reports 0, or a preview
     frame (the doc site's iOS · Android views), sets these instead. Never put device numbers in components. */
  --safe-area-top: env(safe-area-inset-top, 0px);
  --safe-area-bottom: env(safe-area-inset-bottom, 0px);
}

/* =============================================================================
   2. SEMANTIC — light (default)
   ========================================================================== */
:root {
  color-scheme: light;

  /* background */
  --bg-canvas: var(--white);          /* page */
  --bg-default: var(--white);         /* cards, fields, popovers */
  --bg-subtle: var(--gray-50);        /* hover row, secondary surface */
  --bg-muted: var(--gray-100);        /* secondary button, tag hover, progress track */
  --bg-emphasis: var(--gray-150);
  /* loading (skeleton): ONE look for every loading placeholder — a base color with a light band sweeping
     left → right. Components paint:  background: var(--skeleton-shine) 0 0 / 200% 100% no-repeat, <base>;
     animation: var(--skeleton-animation);   (or use the .zg-skeleton utility below) */
  --skeleton-bg: var(--bg-emphasis);            /* gray-150 — the default base */
  --skeleton-shine-color: rgb(255 255 255 / 0.7);
  --skeleton-shine: linear-gradient(100deg, transparent 30%, var(--skeleton-shine-color) 50%, transparent 70%);
  --skeleton-animation: zg-skeleton-shine 1.4s ease-in-out infinite;
  --bg-disabled: var(--black-a5);
  --bg-inverse: var(--gray-900);
  --bg-overlay: var(--dimmed-60);     /* modal backdrop */
  --bg-overlay-light: var(--dimmed-30);
  --bg-tooltip: var(--dimmed-90);
  --bg-sidenav: #292D37;

  /* text */
  --text-primary: var(--gray-900);
  --text-secondary: var(--gray-800);  /* button labels, strong secondary */
  --text-tertiary: var(--gray-700);   /* helper / tooltip body */
  --text-muted: var(--gray-500);
  --text-placeholder: var(--gray-400);
  --text-disabled: var(--gray-400);
  --text-inverse: var(--white);
  --text-on-primary: var(--white);
  --text-link: var(--primary-500);
  --text-danger: var(--red-500);

  /* border */
  --border-subtle: var(--gray-150);
  --border-default: var(--gray-200);
  --border-hover: var(--gray-300);
  --border-strong: var(--gray-400);
  --border-focus: var(--primary-400); /* text field focused: 2px inside (Figma <FocusRing> in fields) */
  --divider: var(--black-a10);        /* translucent: sits naturally on any surface */
  --focus-ring: 0 0 0 2px var(--primary-400);

  /* icon — default = Figma icon master color; subtle for close/clear icons */
  --icon-default: var(--gray-600);
  --icon-subtle: var(--gray-450);
  --icon-strong: var(--gray-800);
  --icon-disabled: var(--gray-300);

  /* brand / action */
  --primary: var(--primary-500);
  --primary-hover: var(--primary-500-hover);
  --primary-press: var(--primary-500-press);
  --primary-subtle: var(--primary-50);
  --primary-subtle-hover: var(--primary-50-hover);
  --primary-subtle-border: var(--primary-100);
  --negative: var(--red-500);
  --negative-hover: var(--red-500-hover);

  /* feedback */
  --danger: #FF4957;
  --info: #1169AD;
  --success: var(--turquoise-500);
  --warning: var(--yellow-500);
  --on-feedback: var(--white);
  --message-success-icon: var(--primary);       /* Figma green #22A06B → primary (user: green isn't a point color) */
  --message-success-text: var(--primary);       /* Figma green #216E4E → primary-500 */
  --message-error-icon: #FF4957;
  --message-error-text: #E3331C;

  /* presence status */
  --status-active: #2ABB7F;
  --status-inactive: #AAAAAA;
  --status-busy: #EB3737;
  --status-unavailable: #E8CB2E;
  --status-off: #666666;

  /* content identity (card types) */
  --identity-todo: var(--turquoise-500);
  --identity-schedule: var(--yellow-500);
  --identity-gathering: var(--purple-500);   /* 의견 모으기 card (Figma: card/identity/fold, checkbox …/folder) */
  --identity-fold: var(--identity-gathering); /* deprecated alias */
  --identity-message: var(--red-500);
  --identity-discussion: var(--darkNavy-500);

  /* progress */
  --progress-track: var(--gray-100);
  --progress-gauge: var(--gray-450);
  --progress-gauge-light: var(--gray-300);
  /* --active: the same band and timing as the loading shine, at the gauge's own strength. The gauge is the
     same gray in light and dark, so its shine is the same too (the skeleton's dark shine is 8% — for dark placeholders). */
  --progress-shine-color: rgb(255 255 255 / 0.7);
  --progress-shine: linear-gradient(100deg, transparent 30%, var(--progress-shine-color) 50%, transparent 70%);
  --progress-ongoing: var(--turquoise-500);
  --progress-done: #3067A8;
  --workspace-1: var(--yellow-500);
  --workspace-2: var(--turquoise-500);
  --workspace-3: #3067A8;

  /* label palette — shared by card label, lozenge, color tags.
     -bg solid / -fg text on solid / -subtle-bg tint / -subtle-fg text on tint */
  --label-1-bg: var(--pink-500);        --label-1-fg: var(--white);     --label-1-subtle-bg: var(--pink-200);       --label-1-subtle-fg: #F26D80;
  --label-2-bg: var(--purple-500);      --label-2-fg: var(--white);     --label-2-subtle-bg: var(--purple-200);     --label-2-subtle-fg: #8F66AE;
  --label-3-bg: var(--sky-500);         --label-3-fg: var(--white);     --label-3-subtle-bg: var(--sky-200);        --label-3-subtle-fg: #3A98B1;
  --label-4-bg: var(--paleYellow-500);  --label-4-fg: var(--black-a65); --label-4-subtle-bg: var(--paleYellow-200); --label-4-subtle-fg: #9C7439;
  --label-5-bg: var(--paleSky-500);     --label-5-fg: var(--white);     --label-5-subtle-bg: var(--paleSky-200);    --label-5-subtle-fg: #5992B5;
  --label-6-bg: var(--lightGreen-500);  --label-6-fg: var(--black-a65); --label-6-subtle-bg: var(--lightGreen-200); --label-6-subtle-fg: #618423;
  --label-7-bg: var(--green-500);       --label-7-fg: var(--black-a65); --label-7-subtle-bg: var(--green-200);      --label-7-subtle-fg: #237A4B;
  --label-8-bg: var(--paleBlue-500);    --label-8-fg: var(--black-a65); --label-8-subtle-bg: var(--paleBlue-200);   --label-8-subtle-fg: #6181D7; /* what the lozenge draws; style said #33477D (user) */
  --label-9-bg: var(--darkPurple-500);  --label-9-fg: var(--white);     --label-9-subtle-bg: var(--darkPurple-200); --label-9-subtle-fg: var(--darkPurple-500);
  --label-10-bg: var(--darkNavy-500);   --label-10-fg: var(--white);    --label-10-subtle-bg: var(--darkNavy-200);  --label-10-subtle-fg: var(--darkNavy-500);

  /* chat */
  --chat-system-bg: var(--highlight);
  --chat-system-inner-bg: var(--black-a7);
  --chat-system-inner-border: var(--black-a3);
  --chat-sender-bg: var(--gray-50);
  --chat-sender-border: var(--gray-300);
  --chat-writer-bg: var(--darkNavy-500);
  --chat-writer-fg: var(--white);
}

/* =============================================================================
   2. SEMANTIC — dark  (PROPOSED values, built on the cool scale — review in index.html)
   ========================================================================== */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg-canvas: var(--cool-900);
  --bg-default: var(--cool-800);
  --bg-subtle: var(--white-a5);               /* see-through: cool-700 was 2–4 RGB off the cool-800 surface (v0.5.51) */
  --bg-muted: var(--cool-600);
  --bg-emphasis: var(--cool-600);
  --skeleton-shine-color: rgb(255 255 255 / 0.08);
  --bg-disabled: var(--white-a10);
  --bg-inverse: var(--gray-50);
  --bg-overlay: var(--black-a65);
  --bg-overlay-light: var(--black-a50);
  --bg-tooltip: var(--cool-600);
  --bg-sidenav: var(--cool-900);

  --text-primary: var(--gray-50);
  --text-secondary: var(--cool-300);
  --text-tertiary: var(--cool-400);
  --text-muted: var(--cool-500);
  --text-placeholder: var(--cool-500);
  --text-disabled: var(--cool-600);
  --text-inverse: var(--gray-900);
  --text-link: var(--primary-400);
  --text-danger: var(--red-400);

  --border-subtle: var(--white-a10);             /* see-through, like --divider: cool-700 was 2–4 RGB off the cool-800 surface (invisible) */
  --border-default: var(--cool-600);
  --border-hover: var(--cool-500);
  --border-strong: var(--cool-400);
  --border-focus: var(--primary-400);
  --divider: var(--white-a10);

  --icon-default: var(--cool-400);
  --icon-subtle: var(--cool-500);
  --icon-strong: var(--cool-300);
  --icon-disabled: var(--cool-600);

  --primary-subtle: rgb(0 127 255 / 0.16);
  --primary-subtle-hover: rgb(0 127 255 / 0.24);
  --primary-subtle-border: rgb(0 127 255 / 0.40);

  --progress-track: var(--white-a10);           /* cool-700 vanished on the cool-800 surface */
  --chat-sender-bg: var(--cool-700);
  --chat-sender-border: var(--cool-600);
  --chat-writer-bg: var(--primary-700);
  --chat-system-inner-bg: var(--black-a10);
  --message-success-text: var(--primary-400);
  --message-error-text: var(--red-400);
  --avatar-placeholder-bg: var(--cool-600);
  --avatar-placeholder-fg: var(--cool-400);
  --avatar-more-fg: var(--cool-300);
  --avatar-all-bg: var(--navy-400);
  --check-border: var(--cool-400);
  --check-hint: var(--cool-600);
  --button-secondary-line-border-hover: var(--cool-300);
  --button-ghost-bg-hover: var(--white-a10);
  --button-ghost-bg-press: var(--white-a20);
  --menu-desc: var(--cool-500);
  --menu-item-bg-filled-gray: var(--cool-500);
  --add-line-hover: var(--cool-300);
  --tab-arrow-line: var(--cool-700);
  --datefield-label: var(--cool-500);
  --badge-neutral-fg: var(--cool-300);
  --badge-neutral-strong-bg: var(--cool-600);
  --tab-pill-bg-active: var(--bg-inverse);   /* darkNavy would vanish on a dark page */
  --tab-pill-fg-active: var(--text-inverse);
  --tab-pill-badge-active-bg: var(--primary);       /* the selected pill is light here: its count is solid primary with a white number (user, v0.5.116; was a light chip + ring) */
  --tab-pill-badge-active-fg: var(--white);
  --tab-pill-badge-ring: transparent;
  --datepicker-weekday: var(--cool-500);
  --datepicker-outside: var(--cool-600);
  --datepicker-sunday: var(--red-400);
  --datepicker-today-bg: rgb(0 127 255 / 0.24);
  --datepicker-today-fg: var(--primary-300);
  --form-label: var(--cool-400);
  --form-label-off: var(--cool-500);
  --rate-off: var(--cool-600);
  --modal-text: var(--cool-400);
  --sheet-handle: var(--cool-600);
  /* file item on dark: a see-through lift, so it reads on any dark surface (a card is the same cool-800) */
  --modal-border: var(--white-a10);
  --options-nav-bg: var(--white-a5);              /* bg-subtle (cool-700) is ~the cool-800 surface on dark */
  --file-item-box-bg: var(--white-a5);
  --file-item-box-line: var(--white-a10);
  --file-item-unknown-bg: var(--white-a5);
  --file-item-action-bg: var(--white-a10);
  --file-item-action-bg-hover: var(--white-a20);
  --filethumb-bg: var(--white-a5);
  --filethumb-border: var(--white-a10);
  --logo-color: var(--white);
  --icon-toggle-bg: var(--white-a5);
  --bottom-nav-line: var(--border-default);
  --bottom-nav-icon: var(--gray-600);
  --bottom-nav-icon-active: var(--white);
  --alarm-bg: rgb(0 0 0 / 0.8);               /* Figma variant=dark */
  --alarm-fg: var(--white);
  --alarm-text: var(--gray-150);
  --alarm-timer-track: var(--gray-600);
  --alarm-app-bg: var(--white-a5);
  --alarm-hover: var(--white-a10);
  --alarm-press: var(--white-a20);
  --icon-button-round-bg: var(--white-a10);
  --icon-button-round-bg-hover: var(--white-a20);
  --comment-reaction-line: var(--border-default);
  --notice-meta: var(--text-muted);
  --notice-drawer-edge: var(--white-a10);
  --comment-input-chip-fg: var(--text-secondary);   /* gray-600 on cool-600 was ~1.3:1 */
  --comment-reaction-fg: var(--text-tertiary);
  --badge-added-fg: var(--primary-300);         /* dark blue would vanish on the dark tint */
  --menu-item-fg-danger: var(--red-400);
  --editor-color-gray: var(--cool-400);
  --editor-color-red: var(--red-400);
  --editor-color-blue: var(--primary-300);
  --editor-color-green: var(--green-500);
  --editor-autofix-bg: color-mix(in srgb, var(--white) 6%, var(--bg-default));
  --editor-autofix-active-bg: var(--white-a10);
  --day-week-sat-bg: color-mix(in srgb, var(--primary-500) 16%, var(--bg-default));   /* tints mixed into the surface: opaque */
  --day-week-sat-bg-hover: color-mix(in srgb, var(--primary-500) 26%, var(--bg-default));
  --day-week-sat-line: color-mix(in srgb, var(--primary-500) 40%, var(--bg-default));
  --day-week-sat-fg: var(--primary-300);
  --day-week-sun-bg: color-mix(in srgb, var(--red-500) 16%, var(--bg-default));
  --link-delete-bg: color-mix(in srgb, var(--red-500) 16%, var(--bg-default));
  --day-week-sun-bg-hover: color-mix(in srgb, var(--red-500) 26%, var(--bg-default));
  --day-week-sun-line: color-mix(in srgb, var(--red-500) 40%, var(--bg-default));
  --day-week-sun-fg: var(--red-300);
  --button-secondary-bg-hover: color-mix(in srgb, var(--cool-600), var(--white) 10%);   /* bg-emphasis = bg-muted on dark */
  --button-secondary-bg-press: color-mix(in srgb, var(--cool-600), var(--white) 18%);
  --button-primary-line-bg-hover: color-mix(in srgb, var(--primary-500) 16%, var(--button-line-bg));   /* tints mixed into the line button's own bg: opaque on any surface */
  --button-secondary-line-bg-hover: color-mix(in srgb, var(--white) 5%, var(--button-line-bg));
  --button-negative-line-bg-hover: color-mix(in srgb, var(--red-500) 16%, var(--button-line-bg));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg-canvas: var(--cool-900);
    --bg-default: var(--cool-800);
    --bg-subtle: var(--white-a5);
    --bg-muted: var(--cool-600);
    --bg-emphasis: var(--cool-600);
    --skeleton-shine-color: rgb(255 255 255 / 0.08);
    --bg-disabled: var(--white-a10);
    --bg-inverse: var(--gray-50);
    --bg-overlay: var(--black-a65);
    --bg-overlay-light: var(--black-a50);
    --bg-tooltip: var(--cool-600);
    --bg-sidenav: var(--cool-900);

    --text-primary: var(--gray-50);
    --text-secondary: var(--cool-300);
    --text-tertiary: var(--cool-400);
    --text-muted: var(--cool-500);
    --text-placeholder: var(--cool-500);
    --text-disabled: var(--cool-600);
    --text-inverse: var(--gray-900);
    --text-link: var(--primary-400);
    --text-danger: var(--red-400);

    --border-subtle: var(--white-a10);
    --border-default: var(--cool-600);
    --border-hover: var(--cool-500);
    --border-strong: var(--cool-400);
    --border-focus: var(--primary-400);
    --divider: var(--white-a10);

    --icon-default: var(--cool-400);
    --icon-subtle: var(--cool-500);
    --icon-strong: var(--cool-300);
    --icon-disabled: var(--cool-600);

    --primary-subtle: rgb(0 127 255 / 0.16);
    --primary-subtle-hover: rgb(0 127 255 / 0.24);
    --primary-subtle-border: rgb(0 127 255 / 0.40);

    --progress-track: var(--white-a10);
    --chat-sender-bg: var(--cool-700);
    --chat-sender-border: var(--cool-600);
    --chat-writer-bg: var(--primary-700);
    --chat-system-inner-bg: var(--black-a10);
    --message-success-text: var(--primary-400);
    --message-error-text: var(--red-400);
    --avatar-placeholder-bg: var(--cool-600);
    --avatar-placeholder-fg: var(--cool-400);
    --avatar-more-fg: var(--cool-300);
    --avatar-all-bg: var(--navy-400);
    --check-border: var(--cool-400);
    --check-hint: var(--cool-600);
    --button-secondary-line-border-hover: var(--cool-300);
    --button-ghost-bg-hover: var(--white-a10);
    --button-ghost-bg-press: var(--white-a20);
    --menu-desc: var(--cool-500);
    --menu-item-bg-filled-gray: var(--cool-500);
    --add-line-hover: var(--cool-300);
    --tab-arrow-line: var(--cool-700);
    --datefield-label: var(--cool-500);
    --badge-neutral-fg: var(--cool-300);
    --badge-neutral-strong-bg: var(--cool-600);
    --tab-pill-bg-active: var(--bg-inverse);   /* darkNavy would vanish on a dark page */
    --tab-pill-fg-active: var(--text-inverse);
    --tab-pill-badge-active-bg: var(--primary);
    --tab-pill-badge-active-fg: var(--white);
    --tab-pill-badge-ring: transparent;
    --datepicker-weekday: var(--cool-500);
    --datepicker-outside: var(--cool-600);
    --datepicker-sunday: var(--red-400);
    --datepicker-today-bg: rgb(0 127 255 / 0.24);
    --datepicker-today-fg: var(--primary-300);
    --form-label: var(--cool-400);
    --form-label-off: var(--cool-500);
    --rate-off: var(--cool-600);
    --modal-text: var(--cool-400);
    --sheet-handle: var(--cool-600);
    /* file item on dark: a see-through lift, so it reads on any dark surface (a card is the same cool-800) */
    --modal-border: var(--white-a10);
    --options-nav-bg: var(--white-a5);
    --file-item-box-bg: var(--white-a5);
    --file-item-box-line: var(--white-a10);
    --file-item-unknown-bg: var(--white-a5);
    --file-item-action-bg: var(--white-a10);
    --file-item-action-bg-hover: var(--white-a20);
    --filethumb-bg: var(--white-a5);
    --filethumb-border: var(--white-a10);
    --logo-color: var(--white);
    --icon-toggle-bg: var(--white-a5);
    --bottom-nav-line: var(--border-default);
    --bottom-nav-icon: var(--gray-600);
    --bottom-nav-icon-active: var(--white);
    --alarm-bg: rgb(0 0 0 / 0.8);
    --alarm-fg: var(--white);
    --alarm-text: var(--gray-150);
    --alarm-timer-track: var(--gray-600);
    --alarm-app-bg: var(--white-a5);
    --alarm-hover: var(--white-a10);
    --alarm-press: var(--white-a20);
    --icon-button-round-bg: var(--white-a10);
    --icon-button-round-bg-hover: var(--white-a20);
    --comment-reaction-line: var(--border-default);
    --notice-meta: var(--text-muted);
    --notice-drawer-edge: var(--white-a10);
    --comment-input-chip-fg: var(--text-secondary);
    --comment-reaction-fg: var(--text-tertiary);
    --badge-added-fg: var(--primary-300);
    --menu-item-fg-danger: var(--red-400);
    --editor-color-gray: var(--cool-400);
    --editor-color-red: var(--red-400);
    --editor-color-blue: var(--primary-300);
    --editor-color-green: var(--green-500);
    --editor-autofix-bg: color-mix(in srgb, var(--white) 6%, var(--bg-default));
    --editor-autofix-active-bg: var(--white-a10);
    --day-week-sat-bg: color-mix(in srgb, var(--primary-500) 16%, var(--bg-default));
    --day-week-sat-bg-hover: color-mix(in srgb, var(--primary-500) 26%, var(--bg-default));
    --day-week-sat-line: color-mix(in srgb, var(--primary-500) 40%, var(--bg-default));
    --day-week-sat-fg: var(--primary-300);
    --day-week-sun-bg: color-mix(in srgb, var(--red-500) 16%, var(--bg-default));
    --link-delete-bg: color-mix(in srgb, var(--red-500) 16%, var(--bg-default));
    --day-week-sun-bg-hover: color-mix(in srgb, var(--red-500) 26%, var(--bg-default));
    --day-week-sun-line: color-mix(in srgb, var(--red-500) 40%, var(--bg-default));
    --day-week-sun-fg: var(--red-300);
    --button-secondary-bg-hover: color-mix(in srgb, var(--cool-600), var(--white) 10%);
    --button-secondary-bg-press: color-mix(in srgb, var(--cool-600), var(--white) 18%);
    --button-primary-line-bg-hover: color-mix(in srgb, var(--primary-500) 16%, var(--button-line-bg));
    --button-secondary-line-bg-hover: color-mix(in srgb, var(--white) 5%, var(--button-line-bg));
    --button-negative-line-bg-hover: color-mix(in srgb, var(--red-500) 16%, var(--button-line-bg));
  }
}

/* =============================================================================
   3. COMPONENT tokens — reference semantic tokens so they follow the theme
   ========================================================================== */
:root {
  /* button — color (primary | secondary | negative) × style (fill | line | ghost) */
  --button-height-sm: var(--size-xs);   /* 24 */
  --button-height-md: var(--size-md);   /* 36 */
  --button-height-lg: var(--size-lg);   /* 40 */
  --button-height-xl: var(--size-xl);   /* 52 — bottom bar */
  --button-radius: var(--radius-sm);
  --button-padding-x: var(--space-12);      /* text edge (md · lg) */
  --button-padding-icon: var(--space-8);    /* icon edge (md · lg) — the icon artboard already carries air */
  --button-padding-sm: var(--space-4);      /* sm, both edges */
  --button-text-bumper: calc(1 / 6);        /* text edge facing an icon gets + artboard × 1/6 — the icon's own average air (user) */
  --button-min-content: 36px;               /* Figma <minWidth>: the content box is never narrower than 36 */
  --button-gap: var(--space-4);

  --button-primary-bg: var(--primary);
  --button-primary-bg-hover: var(--primary-600);        /* hover = one step darker (Figma #007CF9 was 3 RGB off — invisible) (user) */
  --button-primary-bg-press: var(--primary-700);
  --button-primary-fg: var(--text-on-primary);
  --button-primary-line-border: var(--primary);
  --button-primary-line-border-hover: var(--primary-600);
  --button-primary-line-border-press: var(--primary-700);
  --button-primary-line-bg-hover: var(--primary-subtle);  /* line buttons: a light tint inside on hover */
  --button-primary-line-fg: var(--text-secondary);   /* dark label + blue border, as drawn in Figma (user) */
  --button-primary-ghost-fg: var(--text-link);

  --button-secondary-bg: var(--bg-muted);
  --button-secondary-bg-hover: var(--bg-emphasis);   /* gray-150 (Figma hover) */
  --button-secondary-bg-press: var(--gray-200);
  --button-secondary-fg: var(--text-secondary);
  --button-secondary-line-border: var(--border-strong);
  --button-secondary-line-border-hover: var(--gray-450);
  --button-secondary-line-bg-hover: var(--bg-subtle);
  --button-secondary-line-fg: var(--text-secondary);
  --button-secondary-ghost-fg: var(--text-secondary);

  --button-negative-bg: var(--negative);
  --button-negative-bg-hover: var(--red-600);
  --button-negative-bg-press: var(--red-700);
  --button-negative-fg: var(--white);
  --button-negative-line-border: var(--negative);
  --button-negative-line-border-hover: var(--red-600);
  --button-negative-line-bg-hover: var(--red-50);
  --button-negative-line-fg: var(--negative);
  --button-negative-ghost-fg: var(--text-danger);

  --button-line-bg: var(--bg-default);
  --button-ghost-bg-hover: var(--black-a5);   /* Figma secondaryWhite hover */
  --button-ghost-bg-press: var(--black-a10);
  --button-disabled-bg: var(--bg-disabled);
  --button-disabled-fg: var(--text-disabled);
  /* focus (product rule): a 2px primary-500 line, 2px outside the button (Figma <FocusRing>, drawn there in blue-400) */
  --button-focus: var(--primary-500);
  --button-focus-width: 2px;
  --button-focus-gap: 2px;

  /* board label — a board's color chip (Figma 🧬 Icon: board.label). The color is data: set --zg-board-color */
  --board-label-color: var(--navy-500);
  --board-label-edge: var(--white-a30);       /* 2px inner edge */
  --board-label-radius: var(--radius-sm);

  /* icon button — a bare glyph in a 32×32 hit area (Figma <ButtonIcon>) */
  --icon-button-size: 32px;
  --icon-button-radius: var(--radius-sm);
  --icon-button-bg-hover: var(--button-ghost-bg-hover);   /* same quiet overlay as a ghost button */
  --icon-button-bg-press: var(--button-ghost-bg-press);
  --icon-button-tile-size: 20px;                         /* --tile: the visible 20 tile is the button (Figma collapse toggle) */
  --icon-button-tile-bg: var(--bg-subtle);
  --icon-button-tile-bg-hover: var(--bg-muted);
  --icon-button-caption: var(--text-muted);              /* --labeled: 11/16 caption under the glyph */

  /* add button — dashed "add" target (Figma Button Custom: add · addBar) */
  --add-size: 32px;                                       /* square md, and the bar height */
  --add-size-sm: 18px;
  --add-line: var(--border-strong);                       /* square: gray-400 */
  --add-line-hover: var(--gray-600);
  --add-bar-line: var(--border-hover);                    /* bar: gray-300 */
  --add-bar-bg: var(--bg-default);                        /* Figma type=white */
  --add-bar-bg-muted: var(--bg-muted);                    /* Figma type=common */
  --add-icon: var(--icon-default);

  /* text field / dropdown (identical styling in Figma) */
  --field-height-sm: var(--size-xs);
  --field-height-md: var(--size-md);
  --field-radius: var(--radius-sm);         /* Figma TextField r4 */
  --field-padding-x: var(--space-8);
  --field-bg: var(--bg-default);
  --field-bg-hover: var(--bg-subtle);
  --field-bg-disabled: var(--bg-disabled);
  --field-border: var(--border-default);
  --field-border-hover: var(--border-hover);
  --field-border-focus: var(--border-focus);
  --field-focus-width: 2px;                 /* drawn inside, replaces the 1px line */
  --field-gap: var(--space-4);              /* text ↔ leading / trailing */
  --field-icon: var(--icon-default);
  --field-border-disabled: var(--border-subtle);
  --field-fg: var(--text-primary);
  --field-placeholder: var(--text-placeholder);
  --field-fg-disabled: var(--text-disabled);
  --field-icon-disabled: var(--icon-disabled);
  --field-border-error: var(--danger);         /* aria-invalid: 1px, 2px while focused (user) */

  /* blanket — the dim behind a modal (Figma 🧬 Blanket, foundation/dimmed/60) */
  --blanket-bg: var(--bg-overlay);              /* gray-900 60% (dark: black 65%) */
  --blanket-z: var(--z-overlay);

  /* modal — a dialog over the blanket (Figma <Modal>: default · custom) */
  --modal-width-sm: 360px;                      /* dialogs, short forms (Figma default) */
  --modal-width-md: 432px;                      /* lists (board members: 384 content + 24 · 24) */
  --modal-width-lg: 740px;                      /* settings with a side menu */
  --modal-gutter: var(--space-16);              /* never closer to the screen edge */
  --modal-radius: var(--radius-md);             /* 8 */
  --modal-bg: var(--bg-default);
  --modal-border: var(--border-default);        /* 1px gray-200 — a quiet edge so the box doesn't blur into its shadow (user) */
  --modal-shadow: var(--shadow-md);             /* 0 8 24 black 20% */
  --modal-padding-x: var(--space-24);
  --modal-header-padding-top: var(--space-20);
  --modal-header-padding-bottom: var(--space-16);
  --modal-header-line: var(--border-subtle);
  --modal-title: var(--text-primary);           /* 18/24 Medium (H7 medium) */
  --modal-text: var(--gray-600);                /* 14/20 (txtSm/gray600) */
  --modal-gap: var(--space-12);                 /* title ↔ text */
  --modal-body-padding-y: var(--space-20);
  --modal-footer-gap: var(--space-8);
  --modal-z: var(--z-modal);
  --modal-actions-gap: var(--space-4);          /* buttons side by side (bottom bar — ButtonGroup) */
  /* bottom bar (Figma <ModalBottomBar>) */
  --modal-bar-width: 612px;                     /* Figma 613 */
  --modal-bar-inset: var(--space-40);           /* from the screen's bottom */
  --modal-bar-radius: var(--radius-sm);         /* 4 */
  --modal-bar-padding: var(--space-8) var(--space-8) var(--space-8) var(--space-24);
  --modal-bar-gap: var(--space-12);             /* title ↔ buttons */
  --modal-bar-shadow: var(--shadow-xs);         /* dropShadow/type03 */

  /* option count label — a small card-meta chip: icon (+ count); details in a tooltip (Figma <optionCountLabel>) */
  --count-label-height: 20px;                   /* web; --app 28 */
  --count-label-height-app: 28px;
  --count-label-radius: var(--radius-sm);
  --count-label-bg: var(--bg-default);
  --count-label-border: var(--border-subtle);   /* gray-150; hover gray-200 */
  --count-label-border-hover: var(--border-default);
  --count-label-icon: var(--gray-400);          /* hover gray-600 */
  --count-label-icon-hover: var(--gray-600);
  --count-label-text: var(--text-secondary);    /* 11 Medium gray-800 (app 14) */
  --count-label-text-quiet: var(--gray-600);    /* --quiet (Figma secondary): no fill */

  /* work label — a work's type colour + its name (Figma <WorkLabel>: DSP · WFP · TOP · CSP) */
  --work-label-height: 20px;
  --work-label-alpha: 75%;                      /* the type colour at 75% */
  --work-label-fg: var(--white);
  --work-label-work: var(--navy-500);           /* DSP · WORK */
  --work-label-flow: var(--red-500);            /* WFP · 워크플로 (Figma #F85B5F) */
  --work-label-table-order: var(--darkPurple-500);  /* TOP · 테이블오더 */
  --work-label-chat: var(--primary-700);        /* CSP · 채팅 */

  /* table column header — a column's name + the sort it can do (Figma TableColumnheader) */
  --col-header-fg: var(--text-primary);           /* 14/20 gray-900 */
  --col-header-sort: var(--icon-strong);          /* both carets gray-800 while unsorted */
  --col-header-sort-off: var(--icon-disabled);    /* the caret that isn't in use once sorted */
  --col-header-gap: var(--space-4);

  /* logo — the Zigu mark: symbol · symbol + "Zigu" (assets/logo/, from Zigu_BI_white · Zigu_CI_black) */
  --logo-color: #020118;                          /* the CI's symbol colour; dark → white (the BI) */
  --logo-size: 22px;                              /* symbol height (Figma logo.simbol artboard) */
  --logo-wordmark-size: 28px;                     /* symbol + Zigu height; width = height × 121/40 */

  /* day week — pick days of the week (Figma button.dayWeek) */
  --day-week-height: var(--size-md);             /* 36 */
  --day-week-min-width: 54px;
  --day-week-gap: var(--space-8);                 /* Figma 6 → 8: room for the 2px + 2px focus line between days (user) */
  --day-week-radius: var(--radius-sm);
  /* on (toggle row) · can be picked (pick-one row) — the Button primary fill and its hover / press */
  --day-week-on-bg: var(--primary);
  --day-week-on-bg-hover: var(--button-primary-bg-hover);
  --day-week-on-bg-press: var(--button-primary-bg-press);
  --day-week-on-fg: var(--text-on-primary);
  /* off (toggle row) */
  --day-week-off-bg: var(--bg-muted);             /* gray-100 */
  --day-week-off-bg-hover: var(--button-secondary-bg-hover);
  --day-week-off-bg-press: var(--button-secondary-bg-press);
  --day-week-off-line: var(--border-default);     /* gray-200 */
  --day-week-off-fg: var(--text-tertiary);        /* Figma gray-400 (2.2:1) → gray-700 so the day stays readable */
  /* weekend (product rule, user v0.5.65): the off tile only — Saturday light blue + dark blue, Sunday light red + red.
     On / can be picked stay blue, the picked day stays white + blue line, disabled stays the disabled box. */
  --day-week-sat-bg: var(--primary-subtle);       /* primary-50 */
  --day-week-sat-bg-hover: color-mix(in srgb, var(--primary-50), var(--primary-100));
  --day-week-sat-line: var(--primary-subtle-border);   /* primary-100 */
  --day-week-sat-fg: var(--primary-700);          /* 6.3:1 on primary-50 */
  --day-week-sun-bg: var(--red-50);
  --day-week-sun-bg-hover: color-mix(in srgb, var(--red-50), var(--red-100));
  --day-week-sun-line: var(--red-100);
  --day-week-sun-fg: var(--red-800);              /* red-700 is 3.7:1 on red-50 → red-800 4.8:1 */
  /* the picked day (pick-one row): white, blue line, ✓ */
  --day-week-selected-bg: var(--bg-default);
  --day-week-selected-line: var(--primary);
  --day-week-selected-fg: var(--primary);
  /* can't be picked (both rows) — the Button disabled box (Figma THU…SUN: Button State=disabled, outline) */
  --day-week-disabled-bg: var(--button-disabled-bg);
  --day-week-disabled-line: var(--button-disabled-bg);
  --day-week-disabled-fg: var(--button-disabled-fg);

  /* icon toggle — a square that keeps a glyph switched on (Figma <IconToggle>) */
  --icon-toggle-size: 32px;                       /* md; sm = --size-xs 24 */
  --icon-toggle-bg: var(--bg-default);
  --icon-toggle-bg-hover: var(--bg-muted);
  --icon-toggle-icon: var(--icon-default);
  --icon-toggle-on-bg: var(--primary);            /* Figma state=switch drew primary-700 → primary (user, v0.5.67) */
  --icon-toggle-on-bg-hover: var(--button-primary-bg-hover);   /* primary-600, the Button hover step */
  --icon-toggle-on-icon: var(--white);

  /* editor — a block editor (Notion-like; the product runs BlockNote themed with components/editor-blocknote.css) */
  --editor-font-size: var(--body-md-size);       /* 16 */
  --editor-line-height: 28px;                     /* 16/28 (1.75) — airier than body 16/24 for long writing (user, v0.5.82) */
  --editor-gutter: 56px;                          /* room on the left for the side menu (+ · drag handle) */
  --editor-block-padding: var(--space-4);         /* above and below each block — 8 between blocks (user, v0.5.82) */
  --editor-indent: var(--space-24);               /* one nesting level (a child block) */
  --editor-column-gap: var(--editor-gutter);      /* between columns — room for the right column's side menu */
  --editor-peer-flag-height: 16px;                 /* co-editing: another person's name flag on their caret (11 Medium) — v0.5.154 */
  --editor-peer-move: 120ms;                        /* their caret glides to its next place (no jump) */
  --editor-map-width: 560px;                       /* a "지도" block (one place) at most this wide; "여러 곳 지도" fills the line (v0.5.152) */
  --editor-h1-size: var(--h3-size); --editor-h1-lh: var(--h3-lh);   /* 32/40 — 제목 1 = H3 Bold (user) */
  --editor-h2-size: var(--h4-size); --editor-h2-lh: var(--h4-lh);   /* 28/36 — 제목 2 = H4 Bold */
  --editor-h3-size: var(--h5-size); --editor-h3-lh: var(--h5-lh);   /* 24/32 — 제목 3 = H5 Bold */
  --editor-placeholder: var(--text-placeholder);
  --editor-marker: var(--text-tertiary);          /* bullets and numbers */
  --editor-done: var(--text-muted);               /* a checked to-do */
  --editor-quote-line: var(--border-strong);
  --editor-quote-fg: var(--text-secondary);
  --editor-callout-bg: var(--bg-subtle);
  --editor-callout-line: var(--border-subtle);
  --editor-code-bg: var(--bg-subtle);
  --editor-code-inline-bg: var(--bg-muted);       /* `code` inside words — a step darker, so it shows on a callout too */
  --editor-divider: var(--border-default);
  --editor-side-icon: var(--icon-subtle);
  --editor-block-selected: var(--primary-subtle); /* the block a menu is open for */
  --editor-drop: var(--primary);                  /* where a dragged block will land: 2px line */
  --editor-tile-bg: var(--bg-default);            /* slash-menu item tile */
  --editor-tile-line: var(--border-default);
  --editor-tile-size: var(--size-sm);             /* 28 */
  --editor-menu-width: 280px;
  /* words colour OR background (one or the other, product rule) — Figma "설명 고도화 · 글자색상 지정" (745:249482) */
  --editor-color-gray: var(--gray-500);
  --editor-color-red: var(--red-500-hover);       /* Figma #DE5154 */
  --editor-color-blue: var(--primary-700);        /* Figma #0D50B7 → nearest token #0059B2 */
  --editor-color-green: var(--label-7-subtle-fg); /* Figma #216E4E → #237A4B */
  /* background colour = a Lozenge (user): --label-N-subtle-bg / -subtle-fg, --lozenge-radius, --lozenge-padding-x — no editor tokens */
  --editor-video-play-w: 64px; --editor-video-play-h: 44px;   /* the play button on a video's picture */
  --editor-ref-min-width: 260px;                  /* the @ member · # card lists at the caret */
  --editor-palette-width: 280px;                  /* 11 swatches (20, 4 apart) in a row: 없음 + Lozenge 1–10 */
  --editor-swatch: 20px;
  /* symbol auto-fix choice (m2 → ㎡) — Figma "설명 고도화 · 기호자동고침" (771:85838) */
  --editor-autofix-bg: var(--gray-50);
  --editor-autofix-line: var(--border-subtle);    /* gray-150 */
  --editor-autofix-fg: var(--text-muted);          /* gray-500 */
  --editor-autofix-active-bg: var(--black-a10);   /* Figma black 8% */
  --editor-autofix-active-fg: var(--text-tertiary); /* gray-700 */
  --editor-toolbar-tool: var(--size-sm);          /* 28 formatting buttons */

  /* bubble — a small floating layer beside what opened it (Figma 🧬 Layer: bubble) */
  --bubble-width: 384px;
  --bubble-bg: var(--bg-default);
  --bubble-border: var(--border-default);         /* gray-200 */
  --bubble-radius: var(--radius-md);              /* Figma 12 → 8, like every popover */
  --bubble-shadow: var(--shadow-md);              /* Figma type07 (xs) → md like every floating panel, so it lifts off white blocks (user, v0.5.72) */
  --bubble-padding: var(--space-16);                /* 16 all round (user, v0.5.69); Figma 16 · 24 · 20 */
  --bubble-gap: var(--space-12);
  --bubble-title: var(--text-primary);            /* 16/24 Medium */
  --bubble-z: var(--z-dropdown);

  /* side panel — a layer docked to the right; drag its left edge to resize (Figma 🧬 Layer: horizontal.resize) */
  --panel-width: 600px;                           /* starting width */
  --panel-min-width: 360px;
  --panel-max-width: calc(100vw - var(--space-48));
  --panel-bg: var(--bg-default);
  --panel-shadow: var(--shadow-xs);               /* dropShadow/type07 */
  --panel-line: var(--border-subtle);             /* under the header, over the footer */
  --panel-grip: var(--primary-400);               /* the edge while hovered / dragged */
  --panel-z: var(--z-sticky);

  /* text area — several lines of text, with an optional tool row (Figma TextArea) */
  --textarea-min-height: calc(4 * var(--body-sm-lh) + 2 * var(--textarea-padding));   /* 104: four lines — was 220 (Figma 348×220), too tall (user, v0.5.110). Form uses the same */
  --textarea-padding: var(--space-12);
  --textarea-radius: var(--radius-md);            /* 8 */
  --textarea-border: var(--border-subtle);        /* gray-150 */

  /* text field group — a field joined to a dropdown or a button in one box (Figma 🧬 TextField.group) */
  --field-group-divider: var(--divider);          /* black 10% between the field and its button */
  --field-group-button-width: var(--size-md);     /* 36 square */

  /* date move title — "2023년 2월 ⌄  Today" above a calendar (Figma 🧬 DateMoveTitle) */
  --date-title-fg: var(--text-primary);           /* 18/24 Bold */
  --date-title-gap: var(--space-8);

  /* pagination — numbered pages + first · previous · next · last (Figma pagination) */
  --pagination-size: 32px;
  --pagination-gap: var(--space-8);               /* between pages */
  --pagination-group-gap: var(--space-20);        /* arrows ↔ numbers */
  --pagination-fg: var(--text-tertiary);          /* gray-700, 12/16 */
  --pagination-bg-hover: var(--bg-subtle);        /* gray-50 */
  --pagination-current-bg: var(--primary);
  --pagination-current-fg: var(--text-on-primary);
  --pagination-note: var(--text-muted);           /* --infinite: "모두 불러왔어요" · the failed-to-load line (v0.5.149) */

  /* horizontal tab group — a row of tabs that scrolls sideways + a trailing option button (Figma <horizontalTabGroup>) */
  --tab-group-gap: var(--space-12);
  --tab-group-fade: var(--space-24);              /* the soft edge where the row is cut */
  --tab-group-peek: var(--space-48);              /* a picked tab's neighbour peeks in this much (past the fade) — v0.5.115 */

  /* filter select — a dark filter box: name + value, a chip per pick (Figma FilterSelectbox) — dark in both themes */
  --filter-select-bg: var(--warm-600);
  --filter-select-bg-hover: var(--warm-500);
  --filter-select-on-bg: var(--primary-600);      /* something picked */
  --filter-select-on-bg-hover: var(--primary-600-hover);
  --filter-select-label: var(--gray-450);         /* 11/16 */
  --filter-select-label-on: var(--gray-150);
  --filter-select-value: var(--gray-150);         /* 14/20 */
  --filter-select-divider: var(--white-a10);
  --filter-select-chip-bg: var(--black-a50);
  --filter-select-radius: var(--radius-sm);

  /* bottom nav — the app's tab bar at the screen bottom (Figma BottomNav · bottomNav (Native)) */
  --bottom-nav-bg: var(--bg-default);
  --bottom-nav-line: var(--bg-muted);             /* gray-100 top line */
  --bottom-nav-icon: var(--gray-300);
  --bottom-nav-icon-active: var(--gray-900);
  --bottom-nav-item-height: var(--size-lg);       /* 40 */
  --bottom-nav-glyph: var(--icon-xl);             /* 32 artboard */
  --bottom-nav-padding-bottom: var(--space-8);    /* under the tabs, before the safe area (user, v0.5.96; was 0) */

  /* item grid — pick a picture or an icon from a grid (Figma item.grid + itemGrid.parts.*) */
  --item-grid-cell: 68px;
  --item-grid-gap-x: 6px;                         /* as drawn: 5 cells in a 400 sheet with 16 sides */
  --item-grid-gap-y: var(--space-8);
  --item-grid-radius: var(--radius-md);
  --item-grid-bg-hover: var(--bg-subtle);
  --item-grid-selected: var(--primary);
  --item-grid-selected-bg: var(--primary-subtle);
  --item-grid-title: var(--text-secondary);       /* 11/16 */

  /* member — one person in a list: avatar · role pills · name · email (Figma memberList, 🛠️ Parts: positionLabel) */
  --member-gap: var(--space-8);
  --member-name: var(--text-primary);             /* 14/20 Medium */
  --member-sub: var(--text-muted);                /* 12/16 gray-500 */
  --member-pill-line: var(--border-default);      /* position: gray-200 line, gray-500 11/16 */
  --member-pill-fg: var(--text-muted);
  --member-me-bg: var(--primary-700);             /* "Me" */
  --member-me-fg: var(--white);
  --member-leader-bg: var(--red-500);             /* crown badge */
  --member-new: var(--red-500);                   /* 4px dot after the name */

  /* my account — the avatar button at the top bar + its menu (Figma 🧬 MyAccount) */
  --account-button-size: var(--size-md);          /* 36 */
  --account-button-radius: var(--radius-md);
  --account-button-bg-hover: var(--bg-subtle);    /* gray-50 */
  --account-menu-width: 156px;

  /* notice — the alarm list that drops from the bell (Figma 🧬 Notice) */
  --notice-width: 440px;                          /* Figma 340 → 440 (user, v0.5.138); phones (< 600): 100% */
  --notice-bg: var(--bg-default);
  --notice-radius: var(--radius-md);
  --notice-shadow: var(--shadow-md);              /* dropShadow/type01 */
  --notice-line: var(--border-subtle);            /* between items */
  --notice-text: var(--text-secondary);           /* 14/20 gray-800 */
  --notice-meta: var(--gray-600);                 /* 11/16 */
  --notice-arrow: 9px;                            /* the pointer to the bell (Figma 18×10) */
  --notice-read-dot: var(--primary);              /* unread: an 8 dot that is also the 읽음 button (v0.5.137) */
  --notice-source-max: 120px;                     /* where it came from: each crumb's name is cut to this, the upper levels give way first */
  --notice-drawer-shadow: var(--shadow-left);     /* --drawer: a shadow on the left side only (v0.5.139) */
  --notice-drawer-shadow-rtl: var(--shadow-right); /* right to left: docked left, its shadow on the right (v0.5.166) */
  --notice-drawer-edge: transparent;              /* --drawer's left edge — dark: a hairline, the shadow doesn't show there */
  --notice-drawer-z: calc(var(--z-sticky) + 10);  /* over the app's bars (it covers the bell), under the modal layer */

  /* alarm — a notification that pops at the screen corner (Figma 🧬WebAlarm · alarm.app) */
  --alarm-width: 320px;
  --alarm-bg: rgb(255 255 255 / 0.9);             /* Figma white 90% */
  --alarm-fg: var(--text-primary);
  --alarm-text: var(--text-tertiary);             /* 12/16 gray-700 */
  --alarm-radius: var(--radius-sm);
  --alarm-shadow: var(--shadow-xs);
  --alarm-timer-track: var(--gray-100);
  --alarm-timer: var(--primary-200);              /* Figma primary.blue200 #99CCF3 */
  --alarm-app-bg: rgb(246 248 249 / 0.6);         /* gray-50 60% */
  --alarm-app-radius: var(--space-12);            /* 12 */
  --alarm-offset: var(--space-16);
  --alarm-hover: var(--black-a3);                 /* link alarm: a tint laid over the bar (v0.5.91) */
  --alarm-press: var(--black-a5);

  /* link list — saved links with copy · edit · delete (Figma link: empty · typed · filled · +add · +modify) */
  --link-list-width: 340px;
  --link-url: var(--text-link);                   /* 14/20 Medium */
  --link-icon: var(--icon-default);
  --link-delete-bg: var(--red-50);                /* deleting asks once more: the row turns pale red (v0.5.132) */
  --link-confirm-url-min: 120px;                  /* …the address keeps at least this; longer buttons (other languages) go to a second line (v0.5.134) */

  /* comment — one comment: who · when · pictures · files · text · reactions (Figma CommentItem) */
  --comment-indent: var(--space-24);              /* body under the name line */
  --comment-time: var(--text-placeholder);        /* 10/14 gray-400 */
  --comment-photo: 88px;
  --comment-photo-gap: var(--space-2);
  --comment-photo-radius: var(--radius-md);       /* the grid's outer corners */
  --comment-media-width: calc(3 * var(--comment-photo) + 2 * var(--comment-photo-gap));   /* 268: three pictures — files take it too */
  --comment-photo-more-bg: var(--bg-overlay);     /* "+N" over the 6th picture (7+) */
  --comment-photo-more-fg: var(--white);
  --comment-text-tag-lh: var(--tag-height-sm);    /* 24: the line height of a comment whose words hold a Tag */
  --comment-emoticon: calc(2 * var(--comment-photo) + var(--comment-photo-gap));   /* 178: 2 × 2 picture tiles (v0.5.99; was 120) */
  --comment-reaction-bg: var(--bg-default);
  --comment-reaction-line: var(--bg-muted);       /* gray-100 */
  --comment-reaction-fg: var(--gray-600);         /* 12/16 Medium */
  --comment-reaction-on-bg: var(--primary-subtle);
  --comment-reaction-on-line: var(--primary-subtle-border);

  /* comment input — write a comment: text · @ # ☺ · attach (count) · send (Figma CommentInput · AddFile) */
  --comment-input-line: var(--border-default);
  --comment-input-radius: var(--radius-sm);
  --comment-input-chip-bg: var(--bg-muted);       /* @ # ☺ tiles, gray-100 */
  --comment-input-chip-fg: var(--gray-600);
  --comment-input-attach-bg: var(--bg-subtle);    /* gray-50 pill */
  --comment-input-queue-bg: var(--bg-subtle);
  --comment-input-emoticon: 72px;                 /* the emoticon waiting to be sent (v0.5.98) */
  --comment-input-tile: 56px;                     /* Figma 57 */

  /* map — pick or show a place (Figma map.common · map.icon · Parts:map.view) */
  --map-radius: var(--radius-md);
  --map-line: var(--bg-muted);                    /* gray-100 */
  --map-empty: var(--bg-subtle);                  /* before the provider's tiles load */
  --map-pin: var(--primary);
  --map-pin-size: 48px;                           /* the location pin on every map — 1.5 × the 32 it was (v0.5.125) */
  --map-pin-idle: var(--gray-500);               /* Map · Places: a pin not picked yet is gray; only the picked one is --map-pin (v0.5.129) */
  --map-icon-bg: var(--bg-muted);                 /* map.icon tile */
  --map-icon-radius: 6px;                         /* Figma r6 on the 32 tile */
  --map-selected-bg: var(--bg-subtle);            /* the picked place's address bar on top of the map (Figma map.modal filled) — v0.5.120 */
  --map-hint-bg: var(--bg-default);               /* the "찾거나 지도를 눌러 고르세요" chip over an empty map */
  --map-pin-drop: 320ms;                          /* a picked place's pin drops in after the map moves there */
  --map-marker-size: calc(var(--map-pin-size) / 2);   /* Map · Places: the number in the pin's head (24 — the head is 26 at a 48 pin), v0.5.128 */
  --map-place-n-size: 20px;                       /* …the same number circle in the list */
  --map-marker-label-height: 26px;                /* a picked place's title above its pin (words 14) */
  --map-marker-bg: var(--primary);
  --map-marker-fg: var(--text-on-primary);
  --map-place-photo: 56px;
  --map-place-selected-bg: var(--primary-subtle);
  --map-places-list-width: 320px;                 /* the list panel inside the map, on the right (from 560 wide) */
  --map-places-height: 440px;
  --map-places-edit-width: 360px;                 /* the editor panel (v0.5.151) — a little wider than the list, for the fields */
  --map-place-remove-bg: var(--link-delete-bg);   /* ✕ asks once more in the row: the same pale red as every small delete */
  --map-panel-bg: var(--bg-default);
  --map-panel-shadow: var(--shadow-md);

  /* round icon button — a small circle with a glyph (copy · edit · delete in rows) */
  --icon-button-round-size: var(--size-xs);       /* 24 */
  --icon-button-round-bg: var(--bg-subtle);       /* gray-50 */
  --icon-button-round-bg-hover: var(--bg-muted);

  /* spinner — "working…" (Icon.spinner turning; Figma has no Spinner component — from Toast's loading) */
  --spinner-color: var(--icon-subtle);
  --spinner-duration: 0.9s;                     /* one turn; reduced motion: 2.4s */

  /* AI icon (v0.5.142) — Zigu's AI: a small night planet with light comets on tilted orbits (motif: a glowing orb).
     The sphere stays dark in both themes — it is a light source, not a surface. */
  --ai-icon-size: var(--icon-md);               /* md 20 (default) · lg 24 · xl 32 — the Icon frame's circle sizes (user) */
  --ai-icon-deep: var(--navy-900);              /* the sphere's edge */
  --ai-icon-mid: var(--navy-500);               /* the sphere's middle */
  --ai-icon-ocean: var(--primary-400);          /* aurora · comets · rim — Zigu blue first */
  --ai-icon-aqua: var(--turquoise-300);
  --ai-icon-violet: var(--darkPurple-500);
  --ai-icon-lilac: var(--purple-500);
  --ai-icon-rose: var(--pink-500);
  --ai-icon-core: var(--white);                 /* the planet's light */
  --ai-icon-duration: 9s;                       /* idle: the aurora turns once (the core breathes in a third of it) */
  --ai-icon-orbit-duration: 4.2s;               /* idle: the first comet's lap; the others 1.35× · 1.7× */
  --ai-icon-think-duration: 3.2s;               /* thinking: one breath — a lap spiralling into the planet (it swells) · back out (it shrinks) · orbit */
  --ai-icon-tail-lag: 0.24s;                    /* thinking: the tail's orbit closes this much after the head's — it trails along the spiral */
  --ai-icon-frost: var(--primary-100);          /* --still: the ice shell (frozen — v0.5.146) */
  --ai-icon-frost-edge: var(--white);           /* --still: the needles and the iced rim */
  --ai-icon-frost-line: var(--paleSky-500);     /* --still: a 1px ice-blue edge — the circle keeps its edge on a light page (v0.5.147) */
  --ai-icon-freeze-duration: 0.9s;              /* --still: frost grows in (and lets go when it thaws) */

  /* button group — buttons together (Figma 🧬 ButtonGroup: common · capsule · splitButton) */
  --button-group-gap: var(--space-4);
  --button-group-divider: var(--border-default);   /* between capsule segments */

  /* add option button — a dashed "+" that becomes the picked value (Figma addOptionButton) */
  --add-option-size: var(--size-xs);            /* small 24 */
  --add-option-size-md: 32px;                   /* medium */
  --add-option-line: var(--gray-200);           /* 1px dashed; hover gray-400 */
  --add-option-line-hover: var(--gray-400);
  --add-option-icon: var(--gray-300);           /* hover gray-500 */
  --add-option-icon-hover: var(--gray-500);
  --add-option-bg-hover: var(--bg-subtle);

  /* header — the top bar of a panel or a screen (Figma header · header.close · headerContainer) */
  --header-height: 56px;
  --header-bg: var(--bg-default);
  --header-line: var(--border-subtle);
  --header-title: var(--text-primary);          /* 18/24 Medium (h7) */
  --header-action-size: var(--size-lg);         /* icon buttons 40, glyph 24 */

  /* option layout — settings with a side menu (Figma Container: OptionModal web · mobile) */
  --options-nav-width: 208px;                   /* Figma 207 */
  --options-nav-bg: var(--bg-subtle);           /* gray-50 */
  --options-nav-item-height: var(--size-lg);    /* 40 */
  --options-content-padding: var(--space-20) var(--space-24);
  --options-title: var(--text-primary);         /* section title 16/24 Medium */
  --options-desc: var(--text-secondary);        /* 12/16 gray-800 */
  --options-line: var(--border-subtle);
  --options-row-height: 56px;                   /* stacked list row (Figma list(m)) */

  /* file item — one attached file: thumbnail · name · who / size / date · actions (Figma 🧬 FileItem) */
  --file-item-gap: var(--space-8);
  --file-item-name: var(--text-primary);        /* 14/20 */
  --file-item-meta: var(--text-muted);          /* who 12/16 · size | date 11/16, gray-500 */
  --file-item-note: var(--text-secondary);      /* error reason 12/16 gray-800 */
  --file-item-box-bg: var(--bg-default);
  --file-item-box-line: var(--gray-100);        /* --box: 1px #EDEFF0 */
  --file-item-box-radius: var(--radius-md);     /* 8 */
  --file-item-unknown-bg: var(--bg-subtle);     /* no access: gray-50, no line */
  --file-item-action-size: var(--size-xs);      /* round action 24 (download · open folder) */
  --file-item-meta-skeleton: var(--space-48);   /* the size line while uploading: a 48 skeleton bar */
  --file-item-done: var(--primary);             /* finished: the check circle and its ripple (v0.5.106) */
  --file-item-action-bg: var(--bg-subtle);
  --file-item-action-bg-hover: var(--bg-muted);

  /* file field — drop or paste files here (Figma 🧬 FileField) */
  --file-field-height: 60px;
  --file-field-line: var(--gray-300);           /* 1px dashed */
  --file-field-line-active: var(--primary);     /* dragging over */
  --file-field-bg: var(--bg-default);
  --file-field-bg-active: var(--primary-subtle);
  --file-field-text: var(--icon-subtle);        /* 12/16 gray-450 */
  --file-field-icon-bg: var(--bg-subtle);       /* 32 circle */
  --file-field-disabled-bg: var(--black-a5);    /* disabled: black 5% fill + line */
  --file-field-done: var(--primary);            /* done: the check, the words, the line that runs round (v0.5.103) */
  --file-field-done-bg: var(--primary-subtle);  /* done: the check's circle once it settles */
  --file-field-trace-duration: 900ms;           /* the line's one round (eased at both ends, so it's seen going round) */

  /* selector — Zigu's pickers, built on Combobox (Figma "ㄴ common: … (selecter…)" pages) */
  --selector-hint: var(--text-secondary);       /* header line ("8명에게 할당합니다") 12/16 gray-800 */
  --tree-group-height: 44px;                    /* work row: 14 Bold */
  --tree-row-height: var(--size-md);            /* board row 36 */
  --tree-leaf-height: var(--size-lg);           /* card row 40 */
  --tree-indent: var(--space-24);               /* each level steps in 24 */
  --tree-line: var(--border-subtle);
  --tree-open-bg: var(--bg-subtle);             /* an open archived board */
  --tree-group: var(--text-primary);
  --tree-branch: var(--text-tertiary);          /* board name 14 Medium gray-700 */
  --tree-number: var(--text-muted);             /* #123 14 Medium gray-500 */
  --tree-leaf: var(--text-primary);             /* card title 16 Medium */

  /* empty state — nothing here yet: illustration + title + text + actions (Figma 🧬 Empty state) */
  --empty-art-size: 110px;                      /* EmptyIcon lg; --sm 80 */
  --empty-art-size-sm: 80px;
  --empty-max-width: 280px;                     /* text wraps here */
  --empty-title: var(--text-secondary);         /* 16/24 Medium gray-800 (--sm 14/20) */
  --empty-text: var(--gray-600);                /* 12/16 */
  --empty-link: var(--text-link);               /* text link (Figma txtXs/blue500) */
  --empty-gap: var(--space-4);                  /* title ↔ text */
  --empty-actions-gap: var(--space-12);         /* text ↔ buttons */

  /* inline message — a one-line notice where it applies (Figma 🧬inlineMessage: common · topBar) */
  --inline-message-text: var(--text-secondary); /* 14/20 Medium gray-800 */
  --inline-message-icon-size: 16px;             /* status icon sm */
  --inline-message-bar-height: var(--size-md);  /* topBar 36 */
  --inline-message-bar-bg: var(--bg-default);
  --inline-message-bar-line: var(--border-subtle);
  --inline-message-more-shadow: var(--shadow-glow);   /* the "more" panel (dropdown/active) */

  /* status icon — a coloured circle with a white mark (Figma 🛠️ Parts: toast.labelIcon; Toast · Inline message) */
  --status-icon-success: var(--primary);        /* Figma #2BBFCC → primary (user: success is blue everywhere) */
  --status-icon-danger: var(--danger);
  --status-icon-info: var(--info);
  --status-icon-mark: var(--white);

  /* toast — a short note that comes and goes (Figma 🧬 Toast: web · native) */
  --toast-bg: var(--black-a75);                 /* foundation/mono/black075 */
  --toast-fg: var(--white);
  --toast-radius: var(--radius-md);             /* web 8; --app is a pill */
  --toast-padding: var(--space-12) var(--space-16);           /* web: 16/24 text */
  --toast-padding-app: var(--space-8) var(--space-16);        /* app: 14/20 text */
  --toast-min-width: 400px;                     /* web */
  --toast-gap: var(--space-8);
  --toast-icon-size: 20px;                      /* status icon (Parts: toast.labelIcon md) */
  --toast-success: var(--status-icon-success);
  --toast-danger: var(--status-icon-danger);
  --toast-info: var(--status-icon-info);
  --toast-action: var(--primary-300);           /* reaction link (Figma blue300 #56AAFF, an orphan → primary-300) */
  --toast-loading-size: 40px;                   /* loading circle — web 40 · app 36 */
  --toast-loading-size-app: 36px;
  --toast-offset: var(--space-24);              /* from the screen's bottom */
  --toast-z: var(--z-toast);

  /* snack bar — a dark bar with one action button (Figma 🧬 SnackBar); shares the toast surface */
  --snackbar-min-width: 600px;                  /* web; app (native) fills the width */
  --snackbar-padding: var(--space-8) var(--space-16);
  --snackbar-gap: var(--space-24);                /* message ↔ action: at least 24, so they read as two parts (toast gap 8 was too tight — user, v0.5.78) */
  --snackbar-action: var(--toast-action);       /* Figma secondaryWhite (dark text, unreadable on the bar) → primary-300 (user) */
  --snackbar-action-hover: var(--white-a10);
  --snackbar-action-press: var(--white-a20);

  /* bottom sheet — a panel attached to the screen's bottom (Figma "Bottom seat" 🧬 BottomSeat; <ModalBottom> merged in) */
  --sheet-max-width: 480px;                     /* full width on phones; centred on wider screens */
  --sheet-top-gap: var(--space-40);             /* never taller than the screen minus this */
  --sheet-radius: var(--radius-lg);             /* 16, top corners */
  --sheet-bg: var(--bg-default);
  --sheet-shadow: var(--shadow-top);            /* dropShadow/type10 */
  --sheet-padding-x: var(--space-20);
  --sheet-padding-bottom: var(--space-12);      /* + the device's safe area (Figma: 12 + home indicator 34) */
  --sheet-handle: var(--border-subtle);         /* drag handle 60×6, gray-150 */
  --sheet-handle-width: 60px;
  --sheet-handle-height: 6px;
  --sheet-handle-gap: var(--space-12);          /* handle → a titled bar: room above the title (v0.5.92) */
  --sheet-leave-duration: 240ms;                /* pulled down past a third: sucked away */
  --sheet-bar-height: 52px;
  --sheet-line: var(--border-subtle);
  --sheet-title: var(--text-primary);           /* bar 16/24 Medium · message 18/24 Medium */
  --sheet-text: var(--modal-text);              /* 14/20 gray-600 */
  --sheet-hint: var(--text-secondary);          /* header box text 12/16 · options 14 Medium — gray-800 #3C464D */
  --sheet-box-padding-x: var(--space-12);       /* header box rows (hint · search · options) */
  --sheet-actions-gap: var(--space-4);          /* buttons side by side */
  --sheet-z: var(--z-modal);

  /* label text field — edit one label (color + name) that Lozenges then show (Figma <LabelTextField>, 🧬 LabelPalette) */
  --label-swatch-size: var(--size-md);          /* 36: the color button and every palette swatch */
  --label-row-gap: var(--space-4);
  --label-palette-padding: var(--space-12);
  --label-palette-gap: var(--space-8);
  --label-palette-radius: var(--radius-md);     /* 8 */
  --label-palette-cover: var(--black-a50);      /* over the chosen color, with a white check */
  --label-palette-hover: var(--black-a10);
  --label-swatch-radius: var(--radius-md);      /* 8 (Figma 9 — not on the scale) */
  --label-drag-scale: 1.03;                     /* reorder: the grabbed row lifts (v0.5.130) */
  --label-drag-outset: var(--space-4) var(--space-8);   /* …on a card 4 above/below · 8 left/right of the row; the slot has the same footprint */
  --label-drag-shadow: var(--shadow-md);        /* …and casts a deeper shadow than a hover ever does */
  --label-drag-duration: 180ms;                 /* the others sliding aside · the drop gliding into its slot */
  --label-drag-slot-bg: var(--primary-subtle);  /* the slot where the row will land (dashed) */
  --label-drag-slot-line: var(--border-focus);

  /* section accordion — a foldable group in a list (Figma <SectionAccordion>) */
  --accordion-header-height: var(--menu-item-height);   /* 36 */
  --accordion-padding-x: var(--menu-item-padding-x);    /* 12: titles line up with the list items */
  --accordion-title: var(--text-primary);               /* 12/16 Medium */
  --accordion-line: var(--border-subtle);               /* gray-150 under the header */
  --accordion-header-hover: var(--bg-subtle);

  /* form — label · control · message (Figma 🧬 Field, Form: lebel, Form: Message) */
  --form-gap: var(--space-12);                  /* between fields (Figma Board create: 12) */
  --form-field-gap: var(--space-4);             /* label ↔ control ↔ message */
  --form-section-padding: var(--space-24);      /* Figma Form Section */
  --form-label: var(--gray-600);                /* 12/16 Medium (md 14/20) */
  --form-label-off: var(--gray-500);            /* a switch row's label while off — one tone lighter (v0.5.107) */
  --form-label-on: var(--text-primary);          /* …and while on — gray-900 on light, near-white on dark (v0.5.109) */
  --form-options-gap: var(--space-12);          /* radio · checkbox choices stacked */
  --form-options-gap-row: var(--space-24);      /* …side by side (as Radio's row) */
  --form-required: var(--danger);
  --form-message: var(--text-muted);            /* help text, 12/16 Regular */

  /* select — the closed dropdown box (Figma "Dropdown menu" 🧬 Dropdown); shares the --field-* look */
  --select-border-open: var(--border-strong);       /* gray-400 while its menu is open */
  --select-bg-secondary: var(--bg-subtle);          /* --secondary: gray box, no line */
  --select-menu-gap: var(--space-4);
  --select-menu-max-height: 320px;                  /* ~8 options; longer lists scroll */

  /* language select — the capsule that switches the UI language (user v0.5.156, from Zigu Printer Admin's top bar) */
  --language-select-height: var(--size-sm);         /* 28 — a pill; on a phone a 28 circle with the globe only */
  --language-select-bg: var(--bg-default);
  --language-select-border: var(--border-default);
  --language-select-border-hover: var(--border-hover);
  --language-select-fg: var(--text-secondary);      /* the language's own name, 12 */
  --language-select-fg-hover: var(--text-primary);

  /* emoji picker — a grid of emoji on the Menu surface (components/emoji-picker.css) */
  --emoticon-picker-width: 400px;                /* five Item grid cells (68) + 16 sides — Figma's 400 sheet */
  --emoticon-picker-max-height: 360px;           /* four rows and the top of the fifth: it scrolls */
  --emoji-picker-width: 312px;                      /* 8 cells of 36 + 8 each side (phones: screen - 16) */
  --emoji-picker-cell: 36px;
  --emoji-picker-size: 22px;                        /* the emoji in a cell */
  /* phone (< 600px): the options open in a Bottom sheet — rows big enough for a thumb */
  --select-sheet-item-height: 48px;
  --select-sheet-font-size: var(--body-md-size);    /* 16 */
  --select-sheet-line-height: var(--body-md-lh);

  /* menu — panel + items (Figma "Select" page + Dropdown items, merged) */
  --menu-bg: var(--bg-default);
  --menu-border: var(--border-default);
  --menu-radius: var(--radius-sm);
  --menu-shadow: var(--shadow-glow);                /* Figma panel: 0 0 4px 10% */
  --menu-padding-y: var(--space-4);
  --menu-min-width: 120px;
  --menu-item-height: var(--size-md);               /* 36 */
  --menu-item-padding-x: var(--space-12);
  --menu-item-gap: var(--space-8);
  --menu-item-fg: var(--text-primary);
  --menu-item-bg-hover: var(--bg-subtle);
  --menu-item-bg-disabled: var(--bg-disabled);
  --menu-item-fg-disabled: var(--text-disabled);
  --menu-item-fg-selected: var(--primary);          /* default selected look: blue text */
  --menu-heading: var(--text-muted);                 /* a group title inside a menu (Editor slash menu: 기본 블록 · 목록 · 기타) */
  --menu-item-fg-off: var(--text-muted);             /* a switch item that's off: its name one tone down (gray-500, 4.6:1) (user, v0.5.77) */
  --menu-item-fg-danger: var(--red-800);            /* destructive items (삭제 · 나가기) — red-500 is 3.3:1 on white, red-800 5.6:1 (user, v0.5.77) */
  --menu-item-bg-filled: var(--primary);            /* --filled */
  --menu-item-bg-filled-gray: var(--gray-400);      /* --filled-gray */
  --menu-item-fg-filled: var(--text-on-primary);
  --menu-desc: var(--gray-450);                     /* second line, 11/16 */
  --menu-divider: var(--border-subtle);
  --menu-z: var(--z-dropdown);

  /* checkbox / radio */
  --check-bg: var(--bg-default);
  --check-bg-hover: var(--bg-subtle);
  --check-bg-checked: var(--primary);
  --check-bg-disabled: var(--bg-disabled);
  --check-border: var(--gray-400);            /* 2.55:1 on white — user chose a lighter look over 3:1 (gray-450 felt too dark) */
  --check-border-disabled: var(--bg-disabled);
  --check-icon: var(--white);
  --check-icon-disabled: var(--icon-disabled);
  --check-hint: var(--gray-200);              /* faint check before checking (circle-check-marks) */
  --check-hint-bg: var(--bg-subtle);
  --check-mark: var(--icon-subtle);           /* check-marks: bare check, unchecked */
  --check-mark-checked: var(--primary);
  --check-radius: var(--radius-sm);
  --radio-dot: 5px;                           /* Figma: 5px dot in the 18px circle */
  --radio-dot-color: var(--check-icon);
  --radio-dot-disabled: var(--check-icon-disabled);
  --radio-group-gap: var(--space-12);         /* options stacked */
  --radio-group-gap-row: var(--space-24);     /* options side by side — 16 → 24, so each option reads apart (user, v0.5.76) */

  /* switch */
  --switch-bg: var(--bg-muted);
  --switch-bg-hover: var(--bg-emphasis);
  --switch-border: var(--border-subtle);
  --switch-border-hover: var(--border-default);
  --switch-bg-on: var(--primary-subtle);
  --switch-border-on: var(--primary-subtle-border);
  --switch-knob: var(--white);
  --switch-knob-on: var(--primary);
  --switch-knob-disabled: var(--gray-200);
  --switch-label-off: var(--text-muted);          /* a settings row that's off: its label one tone down (gray-500, 4.6:1) — as Menu's switch items (user, v0.5.89) */

  /* tag */
  --tag-height-sm: var(--size-xs);
  --tag-height-md: var(--size-sm);
  --tag-radius: var(--radius-sm);
  --tag-bg: var(--bg-subtle);
  --tag-bg-hover: var(--bg-muted);
  --tag-fg: var(--text-primary);
  --tag-inline-lift: -0.088em;                     /* a Tag in the words (mention · card): from vertical-align middle up to the optical middle of Hangul — em = the text's size (measured) */
  --tag-inline-label-nudge: 1px;                  /* …and its 11px words down to the text's line (measured 0.9px high in the 16 line) */
  --tag-close: var(--icon-subtle);
  --tag-primary-bg: var(--primary);
  --tag-primary-bg-hover: var(--primary-hover);
  --tag-primary-fg: var(--white);
  --tag-primary-close: var(--white-a50);      /* Figma: white 50% (was a20) */
  --tag-bg-press: var(--bg-muted);            /* Figma drew pressed = default; pressed = hover, as everywhere */
  --tag-primary-bg-press: var(--primary-press);
  --tag-close-hover: var(--icon-strong);
  --tag-primary-close-hover: var(--white);
  --tag-gap: var(--space-4);                  /* inside a tag, and between tags in a group */

  /* lozenge — colored label (Figma <lozenge>); colors come from the label palette */
  --lozenge-height: 20px;
  --lozenge-padding-x: var(--space-4);
  --lozenge-radius: var(--radius-sm);
  --lozenge-primary-bg: var(--primary);
  --lozenge-primary-fg: var(--white);

  /* any field — "click to pick" property value (Figma AnyField) */
  --anyfield-bg: var(--bg-subtle);              /* empty: gray-50 box */
  --anyfield-bg-hover: var(--bg-muted);         /* gray-100, also while its popup is open */
  --anyfield-quiet-bg: var(--bg-default);
  --anyfield-quiet-bg-hover: var(--bg-subtle);
  --anyfield-value: var(--text-secondary);      /* filled: gray-800, no box */
  --anyfield-filled-bg-hover: var(--bg-subtle);

  /* date field — labeled date box + start ~ end range (Figma 🧬 DateField); shares the --field-* look */
  --datefield-height: 64px;                     /* label 16 + value 20 inside the box */
  --time-field-panel-min: 160px;                /* the hour | minute columns under a Time field (v0.5.110) */

  /* linear scale · rate (v0.5.110) */
  --scale-height: var(--field-height-md);       /* 36: a box per point */
  --scale-gap: var(--space-4);
  --scale-fg: var(--text-secondary);            /* the number 14/20 Medium */
  --scale-on-bg: var(--primary);                /* the picked point */
  --scale-on-fg: var(--white);
  --scale-ends: var(--text-muted);              /* the words at both ends · the rate's value 12–14 */
  --rate-size: var(--icon-xl);                  /* 32 star (24 artboard scaled) */
  --rate-hit: 36px;                             /* each star's press area */
  --rate-gap: 0px;
  --rate-on: var(--yellow-500);                 /* filled stars */
  --rate-preview: var(--yellow-400);            /* hovering: up to here (a shade lighter than picked) */
  --rate-off: var(--gray-150);                  /* empty stars */
  --rate-off-error: var(--red-200);             /* empty stars of a required, unanswered rate */

  /* sign pad (v0.5.112) */
  --sign-pad-height: 200px;                     /* room to sign (was 160, user v0.5.113) */
  --sign-pad-radius: var(--radius-md);          /* 8, like Text area */
  --sign-pad-bg: var(--field-bg);
  --sign-pad-border: var(--field-border);
  --sign-pad-guide: var(--border-strong);       /* the line to sign on and its × */
  --sign-pad-ink: var(--text-primary);          /* what you see while signing (follows the theme) */
  --sign-pad-ink-export: var(--gray-900);       /* the saved picture: always dark ink on transparent */
  --sign-pad-width: 2.5px;                      /* stroke; a pen's pressure moves it 1.5–4 */
  --datefield-padding: var(--space-8) var(--space-8) var(--space-12);  /* Figma: 8 · 8, value row 36 tall */
  --datefield-gap: var(--space-8);              /* label ↔ value */
  --datefield-label: var(--gray-450);           /* 12/16 */
  --datefield-sep: var(--icon-default);         /* range "~" — gray-600, same as the calendar glyph */

  /* file thumbnail — a file's type tile + the card it came from (Figma 🧬 FileThumbnail) */
  --filethumb-size: 48px;
  --filethumb-size-sm: 36px;
  --filethumb-bg: var(--bg-default);
  --filethumb-border: var(--border-subtle);     /* gray-150 */
  --filethumb-unknown-bg: var(--gray-300);      /* a type we can't show */
  --filethumb-error-bg: var(--black-a75);       /* broken / failed upload */
  --filethumb-loading-bg: var(--border-subtle); /* gray-150 */
  --filethumb-source: 26px;                     /* card-origin label; sm 20 — the same ~55% of the tile */
  --filethumb-source-sm: 20px;

  /* progress bar (Figma <PregressBar>) — colors in the Foundation "progress" group */
  --progress-height: 8px;                       /* md */
  --progress-height-sm: 4px;
  --progress-label: var(--gray-450);            /* "8/10 (80%)", 11/16 */
  --progress-danger: var(--red-500);            /* overdue */
  --progress-danger-track: rgb(248 90 94 / 0.4);/* red-500 at 40% (Figma) */
  --progress-ready: var(--workspace-1);         /* stacked: 준비 yellow */
  --progress-gap: var(--space-4);               /* bar ↔ label */

  /* combobox — searchable popup: header (search) · body (list) · footer (actions) (Figma 🧬 Combobox) */
  --combobox-min-width: 240px;                  /* Figma 229–312 */
  --combobox-radius: var(--radius-sm);
  --combobox-border: var(--border-default);
  --combobox-shadow: var(--menu-shadow);
  --combobox-divider: var(--border-subtle);     /* under the header, over the footer */
  --combobox-padding: var(--space-8);
  --combobox-body-max-height: 288px;            /* 8 rows of 36, then it scrolls */
  --combobox-add-fg: var(--text-link);          /* "+ 새 … 추가": the list's last row, in blue */
  --combobox-empty: var(--text-muted);
  /* card type (Figma selecterCard.depth 550:21353) — rows are the Selector tree's (--tree-*) */
  --combobox-float-min-width: 260px;             /* the @ member · # card lists at the caret of a text box (as the Editor's) */
  --card-list-width: 360px;                     /* Figma 392 incl. sheet padding */

  /* breadcrumbs — where this item lives (Figma 🧬 Breadcrumbs) */
  --breadcrumbs-fg: var(--text-tertiary);       /* gray-700, 12/16 */
  --breadcrumbs-fg-hover: var(--text-secondary);/* gray-800 + underline */
  --breadcrumbs-sep: var(--text-tertiary);      /* "/" */
  --breadcrumbs-gap: var(--space-4);
  --breadcrumbs-lead: var(--icon-sm);           /* 16: work icon, board label, glyph, avatar */
  --breadcrumbs-label-max: 160px;               /* longer names end in "…" + a Tooltip with the full name */
  --breadcrumbs-skeleton-mark: var(--border-subtle);  /* gray-150 */
  --breadcrumbs-skeleton-bar: var(--bg-muted);        /* gray-100 */

  /* date picker — calendar panel (single date · period · time); Figma 🧬 DatePickerV2 reworked */
  --datepicker-padding: var(--space-12);
  --datepicker-cell: var(--size-md);            /* 36: a day's hit area; the period band spans it */
  --datepicker-day: 32px;                       /* the round day mark (Figma) */
  --datepicker-radius: var(--radius-md);        /* popover */
  --datepicker-shadow: var(--shadow-md);
  --datepicker-border: var(--border-default);
  --datepicker-weekday: var(--gray-450);        /* 11/16 Medium header */
  --datepicker-day-fg: var(--text-secondary);   /* gray-800, 14 Medium */
  --datepicker-day-hover: var(--bg-muted);
  --datepicker-outside: var(--gray-300);        /* days of the next/previous month */
  --datepicker-sunday: var(--red-700);          /* Figma holiday red (4.2:1) */
  --datepicker-today-bg: var(--primary-100);
  --datepicker-today-fg: var(--primary-700);
  --datepicker-selected-bg: var(--primary);
  --datepicker-selected-fg: var(--white);
  --datepicker-band: var(--primary-subtle);     /* days inside a period */
  --datepicker-band-preview: var(--bg-muted);   /* while choosing the end */
  --datepicker-timecol: 52px;                   /* hour / minute column */

  /* tabs (Figma 🧬 Tabs + 🛠️ Parts: item) */
  --tab-height: var(--size-md);                 /* 36 */
  --tab-padding-x: var(--space-8);
  --tab-gap: var(--space-12);                  /* between tabs: 8 in Figma, widened a step (user) */
  --tab-fg: var(--text-muted);                  /* gray-500 */
  --tab-fg-active: var(--text-primary);
  --tab-fg-disabled: var(--text-disabled);
  --tab-indicator: var(--primary);              /* 2px under the active tab — Figma gray-900 → primary (user) */
  --tab-badge-active-bg: var(--primary-subtle); /* the active tab's count badge */
  --tab-badge-active-fg: var(--text-link);
  --tab-indicator-hover: var(--border-default); /* gray-200 */
  --tab-indicator-size: 2px;                    /* Figma 3 → 2 (user) */
  --tab-baseline-size: 1px;                     /* Figma 3 → 1 (user) */
  --tab-baseline: var(--divider);               /* black 10% under the whole row */
  --tab-wide-bg-hover: var(--bg-subtle);
  --tab-wide-bg-disabled: var(--bg-disabled);
  --tab-wide-border: var(--border-subtle);
  --tab-arrow-size: 32px;
  /* --pill: round category pills (Figma Parts: search.category + item/iconCircle) */
  --tab-pill-height: var(--size-lg);            /* 40 */
  --tab-pill-padding-x: calc((var(--tab-pill-height) - var(--icon-md)) / 2);  /* 10: an icon-only pill is a 40 circle */
  --tab-pill-gap: var(--space-4);
  --tab-pill-bg: var(--bg-subtle);              /* gray-50 */
  --tab-pill-bg-hover: var(--bg-muted);         /* gray-100 (Figma has no hover) */
  --tab-pill-fg: var(--text-muted);             /* gray-500 */
  --tab-pill-bg-active: var(--darkNavy-500);    /* Figma; the selected pill's count turns Badge --added (user) */
  --tab-pill-fg-active: var(--white);
  --tab-pill-count-drop: 3px;                   /* the count badge hangs 3px below the pill so it never covers a word */
  --tab-pill-badge-active-bg: var(--badge-added-bg);   /* the selected pill's count: Badge --added (user) */
  --tab-pill-badge-active-fg: var(--badge-added-fg);
  --tab-pill-badge-ring: transparent;                  /* dark theme: a ring in the page colour (the pill is light there) */
  --tab-arrow-line: var(--gray-100);
  --tab-arrow-line-hover: var(--border-subtle);

  /* badge (alarm count) */
  --badge-bg: var(--red-500);
  --badge-fg: var(--white);
  --badge-primary-bg: var(--primary);
  --badge-added-bg: var(--primary-subtle);     /* product rule: light blue background … */
  --badge-added-fg: var(--primary-700);        /* … with dark blue text (6.3:1). The class adds no "+" */
  --badge-removed-bg: var(--bg-subtle);        /* gray-50 */
  --badge-removed-fg: var(--red-500);
  --badge-neutral-bg: var(--bg-muted);        /* a plain count (tab counts): light gray pill, gray number */
  --badge-neutral-fg: var(--text-muted);
  --badge-neutral-strong-bg: var(--gray-600);  /* the dark partner: a count over a busy surface (category pills) */
  --badge-neutral-strong-fg: var(--white);
  --badge-height: 16px;                       /* Figma <Badge> */
  --badge-padding-x: var(--space-4);
  --badge-dot: 6px;                           /* unread dot (drawn by hand next to the bell in Figma) */

  /* tooltip — dark bubble (Figma common) · --info white box (Figma moreInfo) */
  --tooltip-bg: var(--bg-tooltip);
  --tooltip-fg: var(--white);
  --tooltip-radius: var(--radius-sm);
  --tooltip-padding: var(--space-4) var(--space-8);
  --tooltip-max-width: 210px;             /* Figma overflow=true box */
  --tooltip-offset: var(--space-4);       /* gap to the trigger (Figma Tooltip: set) */
  --tooltip-caret-w: 10px;
  --tooltip-caret-h: 6px;
  --tooltip-z: var(--z-tooltip);
  --tooltip-info-bg: var(--bg-default);
  --tooltip-info-fg: var(--text-tertiary);
  --tooltip-info-border: var(--border-subtle);
  --tooltip-info-caret-w: 14px;
  --tooltip-info-caret-h: 8px;

  /* slot placeholder — prototyping only, deliberately loud so it can't pass as final UI */
  --slot-border: var(--pink-500);
  --slot-bg: color-mix(in srgb, var(--pink-500) 8%, transparent);
  --slot-fg: var(--label-1-subtle-fg);

  /* icon frame (<Icon> shapes) — glyph artboard = frame × 2/3 */
  --icon-box-circle-bg: var(--bg-subtle);
  --icon-box-circle-line-bg: var(--bg-default);
  --icon-box-circle-line-border: var(--border-default);
  --icon-box-square-fill-bg: var(--bg-subtle);
  --icon-box-square-line-bg: var(--bg-default);
  --icon-box-square-line-border: var(--border-subtle);
  --icon-box-square-dark-bg: var(--bg-inverse);
  --icon-box-square-dark-fg: var(--text-inverse);

  /* avatar */
  --avatar-placeholder-bg: #C6CCE1;          /* avatar-only lavender gray, kept by decision */
  --avatar-placeholder-fg: var(--white);
  --avatar-skeleton-bg: var(--bg-emphasis);
  --avatar-cutout: var(--bg-default);        /* gap ring around status dot, color ring, stack overlap */
  --avatar-cover-hover: var(--black-a5);
  --avatar-cover-press: var(--black-a10);
  --avatar-cover-disabled: color-mix(in srgb, var(--bg-default) 50%, transparent);
  --avatar-focus: var(--primary-400);
  --avatar-all-bg: var(--navy-500);
  --avatar-all-fg: var(--white);
  --avatar-leader-bg: var(--red-500);
  --avatar-anonymous-bg: var(--darkNavy-500);  /* behind an anonymous viewer's planet while it loads */
  --presence-me: var(--primary-500);          /* my presence colour: my avatar ring + where my cursor is (user) */
  --presence-me-fg: var(--white);
  --avatar-text-inset: var(--space-4);        /* nickname: room kept clear on each side of the letters */
  --avatar-latin-min: 9px;                    /* Latin type in avatars (nickname --latin, group "+N"): the smallest; otherwise 36% of the size */
  --avatar-more-bg: var(--bg-muted);
  --avatar-more-bg-hover: var(--bg-emphasis);
  --avatar-more-fg: var(--gray-600);

}

/* =============================================================================
   Typography utility classes — one class per Figma text style.
   Weight modifiers: .fw-medium / .fw-bold  (e.g. class="body-sm fw-bold").
   ========================================================================== */
.h1 { font: var(--font-regular) var(--h1-size)/var(--h1-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h2 { font: var(--font-regular) var(--h2-size)/var(--h2-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h3 { font: var(--font-regular) var(--h3-size)/var(--h3-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h4 { font: var(--font-regular) var(--h4-size)/var(--h4-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h5 { font: var(--font-regular) var(--h5-size)/var(--h5-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h6 { font: var(--font-regular) var(--h6-size)/var(--h6-lh) var(--font-sans); letter-spacing: var(--tracking); }
.h7 { font: var(--font-regular) var(--h7-size)/var(--h7-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-3xs { font: var(--font-regular) var(--body-3xs-size)/var(--body-3xs-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-2xs { font: var(--font-regular) var(--body-2xs-size)/var(--body-2xs-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-xs  { font: var(--font-regular) var(--body-xs-size)/var(--body-xs-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-sm  { font: var(--font-regular) var(--body-sm-size)/var(--body-sm-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-md  { font: var(--font-regular) var(--body-md-size)/var(--body-md-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-lg  { font: var(--font-regular) var(--body-lg-size)/var(--body-lg-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-xl  { font: var(--font-regular) var(--body-xl-size)/var(--body-xl-lh) var(--font-sans); letter-spacing: var(--tracking); }
.body-2xl { font: var(--font-regular) var(--body-2xl-size)/var(--body-2xl-lh) var(--font-sans); letter-spacing: var(--tracking); }
.fw-medium { font-weight: var(--font-medium); }
.fw-bold { font-weight: var(--font-bold); }

/* Component type aliases (kept from Figma, values = body styles) */
.text-badge-xxs, .text-tooltip-sm { font: var(--font-regular) var(--body-2xs-size)/var(--body-2xs-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-badge-xs, .text-tooltip-md, .text-button-sm, .text-field-sm { font: var(--font-regular) var(--body-xs-size)/var(--body-xs-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-badge-sm, .text-label-md, .text-button-md, .text-field-md { font: var(--font-regular) var(--body-sm-size)/var(--body-sm-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-button-lg { font: var(--font-regular) var(--body-md-size)/var(--body-md-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-button-xl { font: var(--font-medium) var(--h7-size)/var(--h7-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-field-xl { font: var(--font-bold) var(--h7-size)/var(--h7-lh) var(--font-sans); letter-spacing: var(--tracking); }
.text-card-label { font: var(--font-bold) var(--body-2xs-size)/var(--body-2xs-lh) var(--font-sans); letter-spacing: var(--tracking); }

/* ---- loading (skeleton): the shared shine. Reduced motion → a still base color. ---- */
@keyframes zg-skeleton-shine { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@media (prefers-reduced-motion: reduce) { :root { --skeleton-animation: none; } }
/* a generic placeholder block: give it a size and a radius; the base is --skeleton-bg unless --zg-skeleton-bg is set */
.zg-skeleton { display: block; background: var(--skeleton-shine) 0 0 / 200% 100% no-repeat, var(--zg-skeleton-bg, var(--skeleton-bg)); animation: var(--skeleton-animation); border-radius: var(--radius-xs); }

/* =============================================================================
   Languages (v0.5.157, docs/I18N.md › Fonts) — each script in its own culture's type. Pretendard draws Hangul and
   Latin (and Han in Korean forms), so Japanese and Chinese put their own fonts first — Japanese and Chinese readers
   get their own Han forms and spacing; Arabic and Devanagari, which Pretendard doesn't have, come right after it.
   Scripts that join or stack their letters (and CJK) get no tracking. Style only, by :lang() — no script branch.
   ========================================================================== */
:lang(ja) {
  --font-sans: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", "Yu Gothic", Meiryo, "Noto Sans JP", var(--font-emoji), "Pretendard Variable", Pretendard, -apple-system, system-ui, sans-serif;
  --tracking: 0;
}
:lang(zh) {
  --font-sans: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", "Noto Sans SC", var(--font-emoji), "Pretendard Variable", Pretendard, -apple-system, system-ui, sans-serif;
  --tracking: 0;
}
:lang(ar) {
  --font-sans: "Pretendard Variable", Pretendard, var(--font-emoji), "Geeza Pro", "Noto Sans Arabic", "Segoe UI", Tahoma, -apple-system, system-ui, sans-serif;
  --font-mono: "ZDS Arabic", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --tracking: 0;
}
/* code in Arabic: monospace fonts that carry Arabic (Menlo, Courier) draw its letters apart — so the Arabic letters
   alone come from a joining Arabic font (unicode-range), and the code's Latin stays monospace */
@font-face {
  font-family: "ZDS Arabic";
  src: local("Geeza Pro"), local("GeezaPro"), local("Noto Sans Arabic"), local("NotoSansArabic-Regular"), local("Segoe UI"), local("Tahoma");
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}
:lang(hi) {
  --font-sans: "Pretendard Variable", Pretendard, var(--font-emoji), "Kohinoor Devanagari", "Noto Sans Devanagari", "Nirmala UI", Mangal, -apple-system, system-ui, sans-serif;
  --tracking: 0;
}
