/* ── REDESIGN LAYER: "Ember Studio" — layered OVER gipity-theme.css ───────────
   New SEMANTIC tokens only. It never redefines --primary / --surface / Water's
   vars, so the :root[data-theme="…"] palettes in gipity-theme.css still resolve
   and degrade cleanly. Dark is the default (the stage scale is dark by design);
   the app-chrome themes re-tune this scale in the themes section below.

   SHARED FILE: this canonical token block is defined once and reused by BOTH
   styles.css (studio surfaces) and editor.css (editor surfaces). It is linked
   from index.html / studio.html / editor.html BEFORE the per-screen stylesheet.
   The content is dictated verbatim by the "Ember Studio" design spec so both the
   studio and editor restyles resolve the same tokens. */
:root {
  /* Signature accent — warm amber→coral "ember". Ownable, harmonized with the
     existing --primary amber, deliberately NOT Riverside indigo. */
  --accent: #ff6a3d;
  --accent-strong: #ff5227;
  --accent-soft: color-mix(in srgb, var(--accent) 16%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 55%, transparent);
  --grad-ember: linear-gradient(135deg, var(--primary) 0%, var(--accent) 100%);
  /* Text/icons placed ON action fills. Every shipped accent is deliberately bright;
     near-black clears 4.5:1 across all of them (white did not). */
  --on-accent: #111015;

  /* RECORD state — dedicated live-red, never the amber brand. */
  --rec: #d92d20;
  --on-record: #ffffff;
  --rec-ring: color-mix(in srgb, var(--rec) 55%, transparent);
  --rec-glow: 0 0 0 6px color-mix(in srgb, var(--rec) 22%, transparent);

  /* Stage surface scale (dark-committed; deeper than the base page black). */
  --stage-0: #0a0a0c;   /* app / stage backdrop */
  --stage-1: #141417;   /* raised surface: header, panels, control bar */
  --stage-2: #1b1b1f;   /* cards, tiles, chips base */
  --stage-3: #26262c;   /* elevated / hover controls */
  --stage-4: #33333b;   /* pressed / active fill */

  /* Hairlines — low-alpha WHITE for modern glassy separation (not hard grey). */
  --line: color-mix(in srgb, #ffffff 8%, transparent);
  --line-strong: color-mix(in srgb, #ffffff 15%, transparent);

  /* Ink (text) on the stage */
  --ink: #f4f3f6;
  --ink-dim: #b9b7c2;
  /* Lightened from #7d7b87 so small dim text clears WCAG AA (~5.2:1 on the
     lightest stage surface, higher on darker ones) while keeping the purple tint. */
  --ink-faint: #8f8c9b;

  /* Semantic status (formalizes the ad-hoc success/danger fallbacks). */
  --ok: #35c46b;
  --danger: #ff5a52;
  /* Caution / warning — amber, deliberately distinct from the coral ember
     --accent so a problem (dropped connection, stalled transfer) reads as caution
     rather than brand. */
  --warn: #f5a623;

  /* Radii — crisp work surfaces; only chips and intentional control bars stay pill-shaped. */
  --r-tile: 10px;
  --r-card: 8px;
  --r-control: 20px;   /* the floating bottom control bar */
  --r-chip: 999px;
  --r-btn: 6px;
  --r-input: 6px;
  --r-sm: 5px;

  /* Control density. Screen-specific chrome may choose compact, standard or touch;
     naming the tiers prevents 30/32/34px one-offs from becoming accidental modes. */
  --control-h-compact: 32px;
  --control-h-standard: 40px;
  --target-touch: 44px;
  --shell-gutter: clamp(12px, 2vw, 24px);

  /* Spacing — finer scale on top of gipity's --space-* */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;

  /* Elevation */
  --shadow-tile: 0 1px 2px rgba(0,0,0,.4), 0 10px 28px rgba(0,0,0,.34);
  --shadow-card: 0 1px 2px rgba(0,0,0,.35), 0 6px 18px rgba(0,0,0,.28);
  --shadow-pop:  0 16px 44px rgba(0,0,0,.52), 0 0 0 1px var(--line);
  --shadow-bar:  0 10px 34px rgba(0,0,0,.55), 0 0 0 1px var(--line-strong);
  --shadow-accent: 0 6px 22px color-mix(in srgb, var(--accent) 42%, transparent);

  /* Focus — visible on the dark stage, two-tone so it reads on any surface */
  --focus-ring: 0 0 0 2px var(--stage-0), 0 0 0 4px var(--accent);

  /* Motion */
  --dur-fast: 120ms; --dur: 200ms; --dur-slow: 340ms;
  --ease: cubic-bezier(.2,.7,.3,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 1ms; --dur: 1ms; --dur-slow: 1ms; }
}

/* The classless base defaults every button to a pill. Regular app controls use
   the tighter shape tokens above; component rules that are genuinely circular
   or pill-shaped still win later with 50% / --r-chip. */
button,
input[type="submit"], input[type="button"], input[type="reset"] {
  border-radius: var(--r-btn);
}
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
select, textarea {
  border-radius: var(--r-input);
}

/* ── App-chrome themes: the Ember half ─────────────────────────────────────────
   The brand/Water half of each palette lives in gipity-theme.css; this is the half
   the studio and the editor actually paint with. Skipping it is the classic
   half-themed bug: the page picks up light inputs and links from Water while every
   panel, tile, dock and rail stays on the dark --stage-* scale.

   Per theme, override the SAME set every time: the accent pair, the five stage
   surfaces, the two hairlines, the three inks. Everything else derives —
   --accent-soft/-line/--grad-ember/--shadow-accent are color-mixes of --accent, and
   --focus-ring is (--stage-0, --accent), so the focus ring re-tunes itself.

   Structure (radii, spacing, motion, elevation geometry) is deliberately NOT here:
   it is shared by every theme and stays in :root above.

   Direction note for the light themes: on the dark scale stage-0 is the deepest
   backdrop and 3/4 are the lifted states. On paper that inverts — stage-2 is the
   white card and the "lifted" states go DOWN in lightness so hover/pressed stay
   visible against white. */

:root[data-theme="light"] {
  /* Darker than the ember coral: this accent has to carry text on a white card,
     where #ff6a3d is only ~2.3:1. */
  --accent: #e0551f;
  --accent-strong: #c4440f;
  --stage-0: #eeebe4;
  --stage-1: #fbfaf8;
  --stage-2: #ffffff;
  --stage-3: #ebe7de;
  --stage-4: #ddd8cc;
  --line: color-mix(in srgb, #1c1a17 12%, transparent);
  --line-strong: color-mix(in srgb, #1c1a17 24%, transparent);
  --ink: #1c1a17;
  --ink-dim: #55504a;
  --ink-faint: #78716a;
  /* Same elevation geometry, a fraction of the alpha — the stage's near-opaque
     black drops read as grey smudges on paper. */
  --shadow-tile: 0 1px 2px rgba(28, 26, 23, .10), 0 10px 28px rgba(28, 26, 23, .10);
  --shadow-card: 0 1px 2px rgba(28, 26, 23, .08), 0 6px 18px rgba(28, 26, 23, .08);
  --shadow-pop:  0 16px 44px rgba(28, 26, 23, .18), 0 0 0 1px var(--line);
  --shadow-bar:  0 10px 34px rgba(28, 26, 23, .16), 0 0 0 1px var(--line-strong);
}

:root[data-theme="blue"] {
  --accent: #4c8dff;
  --accent-strong: #2f77ff;
  --stage-0: #070b16;
  --stage-1: #101728;
  --stage-2: #161f36;
  --stage-3: #202b49;
  --stage-4: #2b385e;
  --line: color-mix(in srgb, #cfe0ff 9%, transparent);
  --line-strong: color-mix(in srgb, #cfe0ff 17%, transparent);
  --ink: #e9eefa;
  --ink-dim: #adbad6;
  --ink-faint: #8593b3;
}

:root[data-theme="dusk"] {
  --accent: #e8863c;
  --accent-strong: #ff9d55;
  --stage-0: #14100d;
  --stage-1: #1e1815;
  --stage-2: #26201b;
  --stage-3: #322a23;
  --stage-4: #40352c;
  --line: color-mix(in srgb, #ffd9b0 9%, transparent);
  --line-strong: color-mix(in srgb, #ffd9b0 18%, transparent);
  --ink: #f5e9dc;
  --ink-dim: #cbb8a5;
  --ink-faint: #a2907e;
}

:root[data-theme="contrast"] {
  --accent: #ffd400;
  --accent-strong: #ffe34d;
  --stage-0: #000000;
  --stage-1: #000000;
  --stage-2: #0d0d0d;
  --stage-3: #1f1f1f;
  --stage-4: #333333;
  /* Hairlines carry the whole layout here — nothing separates two black surfaces
     but the line, so these are opaque-ish instead of the usual 8%/15% whisper. */
  --line: color-mix(in srgb, #ffffff 45%, transparent);
  --line-strong: #ffffff;
  --ink: #ffffff;
  --ink-dim: #ededed;
  --ink-faint: #d4d4d4;
  /* Status colors brightened to clear AAA on pure black. --rec stays a red that
     cannot be confused with the yellow accent. */
  --rec: #d92d20;
  --ok: #4ef08a;
  --danger: #ff7a72;
  --warn: #ffc233;
}

:root[data-theme="forest"] {
  /* A mid-tone green, not the brighter --primary the links use: this one is a FILL
     under white labels, so it is tuned to the same luminance as the default ember. */
  --accent: #2bb083;
  --accent-strong: #229c73;
  --stage-0: #080f0d;
  --stage-1: #101b17;
  --stage-2: #16241f;
  --stage-3: #1f3229;
  --stage-4: #2a4234;
  --line: color-mix(in srgb, #c9ffe6 9%, transparent);
  --line-strong: color-mix(in srgb, #c9ffe6 17%, transparent);
  --ink: #e8f4ee;
  --ink-dim: #adc6ba;
  --ink-faint: #82998d;
}

:root[data-theme="neon"] {
  --accent: #ff4fd8;
  --accent-strong: #ff2bcb;
  --stage-0: #0a0616;
  --stage-1: #150e26;
  --stage-2: #1d1433;
  --stage-3: #2a1e47;
  --stage-4: #382a5c;
  --line: color-mix(in srgb, #d9c8ff 11%, transparent);
  --line-strong: color-mix(in srgb, #d9c8ff 20%, transparent);
  --ink: #f0eaff;
  --ink-dim: #c0b2e6;
  --ink-faint: #9184bd;
}

/* Shared shell appearance menu. The component lives in app-theme-menu.mjs and can
   mount into any nav/header without each page inventing a third theme picker. */
.app-theme-menu { position: relative; margin: 0; padding: 0; overflow: visible; background: transparent; }
.app-theme-menu[open] { padding: 0; }
.app-theme-menu > summary {
  display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--control-h-standard);
  margin: 0; padding: 7px 11px; list-style: none; cursor: pointer;
  color: var(--ink-dim); background: var(--stage-2); border: 1px solid var(--line);
  border-radius: var(--r-chip); font-size: var(--text-sm); font-weight: 700;
}
.app-theme-menu[open] > summary { margin: 0; }
.app-theme-menu > summary::-webkit-details-marker { display: none; }
.app-theme-menu > summary:hover,
.app-theme-menu > summary:focus { color: var(--ink); border-color: var(--accent-line); text-decoration: none; }
.app-theme-menu[open] > summary { color: var(--ink); border-color: var(--accent); }
.app-theme-menu-glyph { color: var(--accent); font-size: 1.05rem; line-height: 1; }
.app-theme-menu-current { color: var(--ink-faint); font-size: var(--text-xs); font-weight: 600; }
.app-theme-menu-panel {
  position: absolute; top: calc(100% + var(--s-2)); right: 0; z-index: 80;
  width: min(340px, calc(100vw - 24px)); max-height: min(70vh, 560px); overflow: auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2);
  padding: var(--s-3); color: var(--ink); background: var(--stage-1);
  border: 1px solid var(--line-strong); border-radius: var(--r-card); box-shadow: var(--shadow-pop);
}
.app-theme-menu-group {
  grid-column: 1 / -1; margin: var(--s-1) 0 0; color: var(--ink-faint);
  font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
}
.app-theme-menu-group:first-child { margin-top: 0; }
.app-theme-menu-option {
  position: relative; display: grid; grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center; gap: var(--s-2); min-height: 58px; margin: 0; padding: var(--s-2);
  text-align: left; color: var(--ink-dim); background: var(--stage-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.app-theme-menu-option:hover { color: var(--ink); background: var(--stage-3); border-color: var(--accent-line); }
.app-theme-menu-option[aria-pressed="true"] { color: var(--ink); background: var(--accent-soft); border-color: var(--accent); }
.app-theme-menu-swatch { display: flex; gap: 2px; }
.app-theme-menu-swatch i { flex: 1 1 0; height: 28px; border: 1px solid var(--line); border-radius: 3px; }
.app-theme-menu-copy { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.app-theme-menu-name { font-size: var(--text-xs); font-weight: 800; }
.app-theme-menu-blurb { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-faint); font-size: 10px; }
.app-theme-menu-check { visibility: hidden; color: var(--accent); font-weight: 900; }
.app-theme-menu-option[aria-pressed="true"] .app-theme-menu-check { visibility: visible; }

@media (max-width: 460px) {
  .app-theme-menu-panel { grid-template-columns: 1fr; }
}

/* Stronger boundaries for users who request contrast without forcing the app's
   bespoke High Contrast palette. Forced-colors then yields fully to system inks. */
@media (prefers-contrast: more) {
  :root { --line: color-mix(in srgb, currentColor 28%, transparent); --line-strong: currentColor; }
  :focus-visible { outline-width: 3px; }
}

@media (forced-colors: active) {
  :root {
    --focus-ring: 0 0 0 3px Highlight;
    --shadow-tile: none; --shadow-card: none; --shadow-pop: none; --shadow-bar: none; --shadow-accent: none;
  }
  :focus-visible { outline: 3px solid Highlight !important; outline-offset: 3px !important; box-shadow: none !important; }
  :is(.primary-btn, .record-btn, .stop-btn, .app-theme-menu-option[aria-pressed="true"]) {
    color: HighlightText !important; background: Highlight !important; border: 1px solid ButtonText !important;
  }
  .app-theme-menu-check { color: Highlight; }
}

@media (prefers-reduced-transparency: reduce) {
  :is(.landing-nav, .controls, .hdr-more-menu, .app-theme-menu-panel) {
    backdrop-filter: none !important;
    background: var(--stage-1) !important;
  }
}

/* Blanket reduced-motion guard — honors the token promise app-wide (studio,
   editor, landing, live) even for animations/transitions that hardcode durations
   instead of the --dur-* tokens. Loaded on every page via tokens.css. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* App-wide focus ring — a consistent ember :focus-visible outline so keyboard
   users get a visible, on-brand ring on EVERY page (incl. live.html, which loads
   tokens.css but not styles.css) and on plain controls that would otherwise fall
   back to Water.css's amber outline. Per-screen rules (.primary-btn:focus-visible
   etc.) are more specific and still win where they set a richer ring. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* App-wide tap-target floor on coarse pointers. Each document screen already has
   a width-gated mobile reflow (schedule.css @760, ideas.css @560, invite.css @520),
   but width is the wrong gate: a touch tablet or touch laptop is wider than every
   one of those breakpoints and kept the desktop-dense sizes. Gate on the pointer
   instead so any finger gets 44px, at any width.

   Scoped to the document screens on purpose. The studio and the editor are NOT in
   this list — their docks, rails and timeline chrome size their own coarse targets
   (see the (pointer: coarse) blocks in studio.css / editor.css) and a blanket 44px
   floor there reflows the dock.

   Written entirely in :where() so it carries ZERO specificity: it is a floor for
   controls nobody sized, and ANY per-screen rule beats it. That matters — a rule
   that could out-specify a deliberate small size would stretch things that must
   stay small (schedule.css `.calendar-event { min-height: 0 }` sits several to a
   month-grid cell). Controls that ARE sized below 44px are raised at their own
   declaration instead; see the coarse block at the end of schedule.css. */
@media (pointer: coarse) {
  :where(body[data-screen="landing"], body[data-screen="invite"], body[data-screen="book"],
         body[data-screen="booking-manage"], body[data-screen="ideas"],
         body[data-screen="schedule"], body.live)
  :where(button, summary, select, [role="button"], a[class*="btn"], a[class*="button"],
         input:not([type="checkbox"]):not([type="radio"]), textarea) {
    min-height: var(--target-touch);
  }
  /* A checkbox/radio can't just grow — it would draw a 44px box. Take the control
     to a comfortable 24px and let its wrapping label carry the rest of the target. */
  :where(body[data-screen="landing"], body[data-screen="invite"], body[data-screen="book"],
         body[data-screen="booking-manage"], body[data-screen="ideas"],
         body[data-screen="schedule"], body.live)
  :where(input[type="checkbox"], input[type="radio"]) {
    min-width: 24px;
    min-height: 24px;
  }
  :where(body[data-screen="landing"], body[data-screen="invite"], body[data-screen="book"],
         body[data-screen="booking-manage"], body[data-screen="ideas"],
         body[data-screen="schedule"], body.live)
  :where(label:has(> :is(input[type="checkbox"], input[type="radio"]))) {
    display: flex;
    min-height: var(--target-touch);
    align-items: center;
  }
}
