/* ==========================================================================
   DOTCLOUD design tokens · Glass & Metal
   --------------------------------------------------------------------------
   Source of truth: Paper file "DOTCLOUD" (01M3PBZS0VZKKRZK74KFHDMDXD),
   page "DOTCLOUD · Glass & Metal", artboards 02 to 13. 206 tokens, same
   names as in Paper. Generated 2026-09-29.

   NOT WIRED IN. Nothing loads this file yet. app.html keeps its own :root
   until the chrome is refactored; see TOKEN_MAP.md for the old-to-new map.

   Structure follows the Design System Surf dev handoffs:
     1. Primitives  raw values. Never referenced by component code.
     2. Semantic    role names. The only layer components may use.
     3. Modes       prefers-reduced-motion only.

   Dark only, by design. Light mode is a written non-goal, so there is no
   :root light block and no [data-theme] switch. Spacing has no density
   modes yet (see TOKEN_MAP.md, [NOTE] density).

   Where Paper stores a literal (the older semantic colours were entered as
   hex), this file expresses the same value as a var() to its primitive.
   The resolved values are identical.
   ========================================================================== */


/* ==========================================================================
   1. PRIMITIVES
   Raw values. Do not reference these in component or layout code.
   ========================================================================== */

:root {

  /* ---- Colour · neutral ladder ---------------------------------------- */
  --color-neutral-0:    #FFFFFF; /* the primary hover fill only */
  --color-neutral-50:   #F2F2F2;
  --color-neutral-200:  #C9C9C9;
  --color-neutral-300:  #A3A3A3;
  --color-neutral-400:  #8A8A8A;
  --color-neutral-800:  #343434;
  --color-neutral-850:  #2A2A2A;
  --color-neutral-900:  #1F1F1F;
  --color-neutral-950:  #141414;
  --color-neutral-1000: #0A0A0A;

  /* ---- Colour · cream, the one emphasis ------------------------------- */
  --color-cream-50:  #FFFAF2;
  --color-cream-100: #F2EDE4; /* one lightness step down, same hue */

  /* ---- Colour · state hues -------------------------------------------- */
  --color-red-dot-500: #EC6940; /* the gallery's red dot */
  --color-red-600:     #E4614F;
  --color-green-500:   #7FB069;
  --color-amber-400:      #FF9E02; /* Blaze template palette, fg: L .78 C .17, the state grade */
  --color-periwinkle-400: #A99DF8; /* Orchid template palette, fg: L .74 C .13, the state grade */

  /* ---- Typography ------------------------------------------------------
     Paper holds family names only; the fallback stacks are added here and
     match what app.html writes today. */
  --font-display: "Instrument Serif", Georgia, serif;
  --font-sans:    "Geist", sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, monospace;
  --font-prose:   "Inter", -apple-system, sans-serif;

  --text-caps:       10px; /* uppercase only, never a sentence */
  --text-label:      11px;
  --text-body-sm:    12px; /* the smallest sentence */
  --text-body:       13px;
  --text-title:      16px;
  --text-headline:   22px;
  --text-display:    32px;
  --text-display-lg: 48px;
  --text-display-xl: 72px;

  --font-weight-regular:  400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;

  --tracking-tight:   -0.02em;
  --tracking-display: -0.01em;
  --tracking-none:     0em;
  --tracking-caps:     0.06em;

  --leading-caps:       12px;
  --leading-label:      14px;
  --leading-body-sm:    16px;
  --leading-body:       18px;
  --leading-title:      20px;
  --leading-headline:   28px;
  --leading-display:    36px;
  --leading-display-lg: 52px;
  --leading-display-xl: 76px;

  /* ---- Spacing scale · base 4, plus DOTCLOUD's 6 and 20 --------------- */
  --spacing-0:    0px;
  --spacing-100:  2px;
  --spacing-200:  4px;
  --spacing-250:  6px;   /* DOTCLOUD step: control internals */
  --spacing-300:  8px;
  --spacing-400:  12px;
  --spacing-500:  16px;
  --spacing-550:  20px;  /* DOTCLOUD step: sidebar and card inset */
  --spacing-600:  24px;
  --spacing-700:  32px;
  --spacing-800:  40px;
  --spacing-900:  48px;
  --spacing-1000: 64px;
  --spacing-1100: 80px;
  --spacing-1200: 96px;
  --spacing-1300: 128px;

  /* ---- Radius scale ---------------------------------------------------- */
  --radius-none: 0px;
  --radius-xs:   2px;
  --radius-sm:   4px;
  --radius-md:   8px;
  --radius-lg:   12px;
  --radius-xl:   16px;
  --radius-2xl:  24px;
  --radius-3xl:  32px;
  --radius-full: 999px; /* pill sentinel: resolves to the aspect ratio */

  /* ---- Border width scale · Surf 0, 0.5, 1, 2, 4 ---------------------- */
  --border-width-none: 0px;
  --border-width-xs:   0.5px; /* renders as 1px on a 1x screen */
  --border-width-sm:   1px;
  --border-width-md:   2px;
  --border-width-lg:   4px;   /* not used by the chrome today */

  /* ---- Opacity --------------------------------------------------------- */
  --opacity-clear:    5%;
  --opacity-disabled: 40%;
  --opacity-smoked:   72%;  /* the scrim, and Smoked as Paper draws it; an adaptive panel reads its own */
  --opacity-smoked-min: 5%;  /* adaptive floor: over near black, as clear as Clear */
  --opacity-smoked-max: 92%; /* adaptive ceiling: over white, as solid as Matte */
  --opacity-matte:    92%;

  /* ---- Breakpoints and containers -------------------------------------- */
  --breakpoint-sm: 600px;
  --breakpoint-md: 1024px;
  --breakpoint-lg: 1440px;

  --container-sidebar: 280px;
  --container-modal:   520px;
  --container-reading: 640px;

  /* ---- Motion · durations. Each pair is opening then closing. -------- */
  --motion-duration-instant:        0ms;    /* reduced-motion targets only */
  --motion-duration-quick:          160ms;
  --motion-duration-quick-exit:     110ms;
  --motion-duration-standard:       220ms;
  --motion-duration-standard-exit:  150ms;
  --motion-duration-slow:           360ms;
  --motion-duration-slow-exit:      250ms;
  --motion-duration-hide-work:      1100ms; /* glimm's sweep */
  --motion-duration-hide-work-fade: 700ms;  /* glimm's fade */

  /* ---- Motion · easing. No overshoot in the chrome. ------------------- */
  --motion-ease-out: cubic-bezier(0.22, 1, 0.36, 1);   /* enter */
  --motion-ease-in:  cubic-bezier(0.55, 0, 0.67, 0.2); /* exit */

  /* ---- Motion · distance and scale ------------------------------------- */
  --motion-distance-none: 0px;
  --motion-distance-sm:   8px;
  --motion-scale-none:    1;
  --motion-scale-sm:      0.96;
}


/* ==========================================================================
   2. SEMANTIC
   Role names. Use these, and only these, in component and layout code.
   ========================================================================== */

:root {

  /* ---- Colour · background -------------------------------------------- */
  --color-bg-base-canvas:  var(--color-neutral-1000); /* the unlit wall */
  --color-bg-base-surface: var(--color-neutral-950);  /* the instrument */
  --color-bg-base-raised:  var(--color-neutral-900);  /* wells, inputs */

  --color-bg-action-primary-default:   var(--color-cream-50);
  --color-bg-action-primary-hover:     var(--color-neutral-0);    /* on-primary 19.8:1 */
  --color-bg-action-primary-pressed:   var(--color-cream-100);    /* on-primary 17.0:1 */
  --color-bg-action-secondary-default: var(--color-neutral-850);  /* fg.primary 12.8:1 */
  --color-bg-action-secondary-hover:   var(--color-neutral-800);  /* fg.primary 11.1:1 */
  --color-bg-action-secondary-pressed: var(--color-neutral-900);  /* fg.primary 14.7:1 */
  --color-bg-action-ghost-hover:       var(--color-neutral-800);  /* fg.primary 11.1:1 */
  --color-bg-action-ghost-pressed:     var(--color-neutral-850);  /* fg.primary 12.8:1 */

  --color-bg-state-selected: var(--color-cream-50);   /* on-primary 19.1:1 */
  --color-bg-state-disabled: var(--color-neutral-900);

  /* ---- Colour · foreground · ratios on surface / canvas / raised ------ */
  --color-fg-base-primary:   var(--color-neutral-50);   /* 16.5 / 17.7 / 14.7 */
  --color-fg-base-secondary: var(--color-neutral-200);  /* 11.1 / 12.0 / 10.0 */
  --color-fg-base-tertiary:  var(--color-neutral-300);  /*  7.3 /  7.9 /  6.5 */
  --color-fg-base-disabled:  var(--color-neutral-400);  /*  5.3 /  5.7 /  4.8, exempt */
  --color-fg-on-primary:     var(--color-neutral-1000); /* 19.1 on cream */
  --color-fg-emphasis:       var(--color-cream-50);     /* cream as TEXT: 19.1 canvas, 17.7 surface, 15.9 raised */

  /* ---- Colour · lines. Decoration at 1.1 to 1.6:1; never the only
          thing that marks a control. ---------------------------------- */
  --color-border-base-subtle:  color-mix(in srgb, var(--color-neutral-0) 5%, transparent);
  --color-border-base-default: color-mix(in srgb, var(--color-neutral-0) 8%, transparent);
  --color-border-base-strong:  color-mix(in srgb, var(--color-neutral-0) 16%, transparent);
  --color-border-selected:     color-mix(in srgb, var(--color-cream-50) 50%, transparent); /* 5.2:1 on surface */
  --color-border-focus:        var(--color-cream-50);  /* 17.7:1 on surface */

  /* ---- Colour · focus ---------------------------------------------------
     Same value as border.focus. focus.default names the ring; border.focus
     is the one to put in outline-color. */
  --color-focus-default: var(--color-cream-50);

  /* ---- Colour · state · ratios on surface ----------------------------- */
  --color-state-modified: var(--color-red-dot-500); /* 5.8; a dot only on hover fills */
  --color-state-negative: var(--color-red-600);     /* 5.4; icons only on secondary and hover */
  --color-state-live:     var(--color-green-500);   /* 7.3 */
  --color-state-warning:  var(--color-amber-400);      /* 8.9 on surface, 6.0 on hover */
  --color-state-info:     var(--color-periwinkle-400); /* 7.8 on surface, 5.3 on hover */

  /* ---- Colour · glass and scrim ---------------------------------------- */
  /* The three glass grades (03 Materials). Decided 2026-09-29, option D:
     Matte and Clear are fixed; Smoked adapts. It takes the lowest opacity,
     between --opacity-smoked-min and -max, at which every text shade it carries
     reaches --contrast-glass-min over the brightest spot of the work behind it,
     read after the blur. It eases over --motion-glass-adapt-duration, never
     flickers, and holds still in Break. Clear drops its blur to 0 when it sits
     in front of a work. */
  --contrast-glass-min: 4.5; /* WCAG AA for the smallest shade on the panel */
  --blur-glass-clear:  6px;
  --blur-glass-smoked: 16px;
  --blur-glass-matte:  24px;
  --color-glass-matte:      color-mix(in srgb, var(--color-neutral-950) var(--opacity-matte), transparent);  /* blur 24 + grain */
  --color-glass-smoked:     color-mix(in srgb, var(--color-neutral-1000) var(--opacity-smoked), transparent); /* blur 16; this resolves at :root, so an adaptive panel redeclares the mix with its own --opacity-smoked */
  --color-glass-clear:      color-mix(in srgb, var(--color-neutral-0) var(--opacity-clear), transparent);     /* blur 6 */
  --color-glass-edge-light: color-mix(in srgb, var(--color-cream-50) 24%, transparent); /* inset 0 1px 0 */
  --color-scrim:            color-mix(in srgb, var(--color-neutral-1000) var(--opacity-smoked), transparent);

  /* ---- Spacing · semantic families (06) --------------------------------
     Stack is vertical flow, inline horizontal, inset padding, gap equal
     siblings, section macro rhythm. */
  --spacing-stack-xs: var(--spacing-200);  /*  4 */
  --spacing-stack-sm: var(--spacing-300);  /*  8 */
  --spacing-stack-md: var(--spacing-500);  /* 16 */
  --spacing-stack-lg: var(--spacing-700);  /* 32 */
  --spacing-stack-xl: var(--spacing-900);  /* 48 */

  --spacing-inline-xs: var(--spacing-200); /*  4 */
  --spacing-inline-sm: var(--spacing-250); /*  6 */
  --spacing-inline-md: var(--spacing-300); /*  8 */
  --spacing-inline-lg: var(--spacing-400); /* 12 */
  --spacing-inline-xl: var(--spacing-500); /* 16 */

  --spacing-inset-xs: var(--spacing-300);  /*  8 */
  --spacing-inset-sm: var(--spacing-400);  /* 12 */
  --spacing-inset-md: var(--spacing-500);  /* 16 */
  --spacing-inset-lg: var(--spacing-550);  /* 20 */
  --spacing-inset-xl: var(--spacing-600);  /* 24 */

  --spacing-gap-xs: var(--spacing-200);    /*  4 */
  --spacing-gap-sm: var(--spacing-300);    /*  8, the floor between two controls */
  --spacing-gap-md: var(--spacing-400);    /* 12 */
  --spacing-gap-lg: var(--spacing-500);    /* 16 */
  --spacing-gap-xl: var(--spacing-600);    /* 24 */

  --spacing-section-xs: var(--spacing-600);  /* 24 */
  --spacing-section-sm: var(--spacing-700);  /* 32 */
  --spacing-section-md: var(--spacing-900);  /* 48 */
  --spacing-section-lg: var(--spacing-1000); /* 64 */
  --spacing-section-xl: var(--spacing-1200); /* 96 */

  /* ---- Size · control heights (06) ------------------------------------- */
  --size-control-compact:   var(--spacing-600); /* 24: preset pills, toggles */
  --size-control-default:   var(--spacing-700); /* 32: buttons, fill rows, selects */
  --size-control-prominent: var(--spacing-800); /* 40: the dock */
  --size-control-touch:     var(--spacing-900); /* 48: Play and Break */

  /* ---- Shape · radius by role (07). A radius never changes on hover,
          press, focus or selection. ---------------------------------- */
  --shape-track:    var(--radius-xs);   /*  2 slider track, progress */
  --shape-chip:     var(--radius-sm);   /*  4 chips, keycaps, toggle halves */
  --shape-control:  var(--radius-md);   /*  8 buttons, inputs, selects, preset pills */
  --shape-tab:      var(--radius-md);   /*  8 rail 12 minus inset 4 */
  --shape-card:     var(--radius-lg);   /* 12 cards, dropdowns, dock pills */
  --shape-tab-rail: var(--radius-lg);   /* 12 */
  --shape-panel:    var(--radius-xl);   /* 16 sidebar, toolbars, dock */
  --shape-sheet:    var(--radius-2xl);  /* 24 */
  --shape-modal:    var(--radius-2xl);  /* 24, was 20 */
  --shape-pill:     var(--radius-full); /* tempo pill, hallmarks */

  /* ---- Border width · semantic, and the two offsets -------------------- */
  --border-width-hairline: var(--border-width-xs); /* retina hairlines, never structure */
  --border-width-default:  var(--border-width-sm);
  --border-width-strong:   var(--border-width-sm); /* 1 as drawn in 07; Surf default 2 */
  --border-width-selected: var(--border-width-sm); /* 1 as drawn in 07; Surf default 2 */
  --border-width-focus:    var(--border-width-md); /* the only 2px line */

  --border-offset-inset: -1px; /* lines sit inside the edge */
  --border-offset-focus:  2px; /* the ring stands off the control */

  /* ---- Elevation · shadows and rings (08) ------------------------------
     Single-layer values, not Surf's two-layer ones. Cast shadows from a
     sibling under glass, never from the glass node: glass clips with
     overflow hidden. Combine with a comma when a control needs both:
     box-shadow: var(--shadow-2), var(--ring-halo). */
  --shadow-1: 0 1px 2px rgb(0 0 0 / 30%);   /* plane 1 surface: instruments */
  --shadow-2: 0 8px 24px rgb(0 0 0 / 40%);  /* plane 2 raised: menus, toolbar */
  --shadow-3: 0 24px 64px rgb(0 0 0 / 55%); /* plane 4 elevated: sheets, modals */

  --ring-halo:       0 0 0 3px rgb(255 250 242 / 13%); /* cream 13%: decorative, not focus */
  --ring-halo-hover: 0 0 0 3px rgb(255 250 242 / 26%); /* cream 26% */

  /* ---- Elevation · named layers (z-index, as it is today) -------------- */
  --layer-canvas:     1;
  --layer-instrument: 50;
  --layer-raised:     100;
  --layer-toast:      200;
  --layer-sheet:      400;
  --layer-modal:      10000;
  --layer-command:    11000;

  /* ---- Motion · intents. Use duration, easing and distance from the same
          intent together. Closing is always quicker than opening. ------ */
  --motion-feedback-duration:      var(--motion-duration-quick);          /* 160 */
  --motion-feedback-exit-duration: var(--motion-duration-quick-exit);     /* 110 */
  --motion-feedback-easing:        var(--motion-ease-out);

  --motion-enter-duration: var(--motion-duration-standard);               /* 220 */
  --motion-enter-easing:   var(--motion-ease-out);
  --motion-enter-distance: var(--motion-distance-sm);                     /* rises 8 */
  --motion-enter-scale:    var(--motion-scale-sm);                        /* glass: 0.96 to 1 */

  --motion-exit-duration: var(--motion-duration-standard-exit);           /* 150 */
  --motion-exit-easing:   var(--motion-ease-in);

  --motion-sheet-enter-duration: var(--motion-duration-slow);             /* 360 */
  --motion-sheet-exit-duration:  var(--motion-duration-slow-exit);        /* 250 */

  --motion-hide-work-duration:      var(--motion-duration-hide-work);      /* 1100 */
  --motion-hide-work-fade-duration: var(--motion-duration-hide-work-fade); /* 700 */
  --motion-glass-adapt-duration:    var(--motion-duration-hide-work-fade); /* 700: slow enough that Smoked never flickers */

  /* Liquid metal (16 · System 01): on hover a rim's light turns once, and
     stops. Only rims move; nothing loops or runs on its own clock. */
  --motion-metal-turn:     120deg;
  --motion-metal-duration: var(--motion-duration-slow);                   /* 360 */

  /* ---- Density (16 · System 03). Three settings of one grid: only height
          and spacing change; type, radii and the 24 target floor stay.
          Default here, the other two under [data-density] below. Nothing
          sets data-density yet: whether to offer it is David's call (V). -- */
  --density-row:     var(--size-control-default);  /* 32 */
  --density-gap:     var(--spacing-300);           /*  8 */
  --density-section: var(--spacing-600);           /* 24 */
}

:root[data-density="compact"] {
  --density-row:     var(--size-control-compact);  /* 24, exactly the floor */
  --density-gap:     var(--spacing-250);           /*  6 */
  --density-section: var(--spacing-500);           /* 16 */
}
:root[data-density="comfortable"] {
  --density-row:     var(--size-control-prominent); /* 40 */
  --density-gap:     var(--spacing-400);            /* 12 */
  --density-section: var(--spacing-700);            /* 32 */
}


/* ==========================================================================
   3. MODES · reduced motion
   08 says: travel drops to 0, durations shorten, liquid metal and entrance
   animations stop. It gives no numbers, so durations follow Surf's fallback
   rule, one step down the ladder ([NOTE] in TOKEN_MAP.md). The pillar sweep
   is already skipped under reduced motion (pillarSweepReduced in
   app-main.js), so its durations go to 0.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-enter-duration:       var(--motion-duration-quick);          /* 220 to 160 */
    --motion-exit-duration:        var(--motion-duration-quick-exit);     /* 150 to 110 */
    --motion-sheet-enter-duration: var(--motion-duration-standard);       /* 360 to 220 */
    --motion-sheet-exit-duration:  var(--motion-duration-standard-exit);  /* 250 to 150 */

    --motion-hide-work-duration:      var(--motion-duration-instant);
    --motion-hide-work-fade-duration: var(--motion-duration-instant);

    --motion-enter-distance: var(--motion-distance-none); /* no travel */
    --motion-enter-scale:    var(--motion-scale-none);    /* no scale-in */
    --motion-metal-turn:           0deg;                            /* no turn: the fill lifts alone */
    --motion-glass-adapt-duration: var(--motion-duration-instant);  /* Smoked snaps, on the same 3-point rule */

    /* Feedback stays at 160 and 110: already the shortest step. Easings
       stay: ease.out has no overshoot to calm. */
  }
}
