/* ==========================================================================
   ROCKJAW LIVE Planner -- TikTok LIVE run sheets and show diary.
   THEME: EcomBase / CEOdeck "Daylight", INHERITED VERBATIM.

   PROVENANCE (do not re-derive): every value from `:root {` down to the end of
   the html[data-theme="dark"] block is copied byte-for-byte from
     /Users/sach/cortexia/workspace/marketplace_pricer/static/tokens.css
   which itself mirrors the source of truth at
     /Users/sach/cortexia/econ_base/tokens.css
   This tool introduces NO new colour into the estate. The only addition is the
   APP-LOCAL ROLES block further down, and every colour in it is an alias of a
   token that already exists and has already been contrast-measured by the
   estate. That is deliberate: a fourth tool inventing a fifth amber is how an
   estate stops looking like one product.

   The original Ladder header follows, unedited, because the notes in it explain
   why these values are what they are.
   --------------------------------------------------------------------------
   Ladder -- marketplace pricing desk.
   THEME: EcomBase "Daylight" (retheme 2026-09-22; was "Machined Graphite").

   The colour, edge and depth values below are taken from the source of truth,
   /Users/sach/cortexia/econ_base/tokens.css, so this page reads as somewhere
   you arrived at FROM the EcomBase portal rather than a lookalike.
   Do not "improve" a value here; change it in econ_base/tokens.css and mirror.

   WHAT MOVED IN THIS PASS (names are frozen, only VALUES changed):
     * the ground inverts, dark graphite -> white; the neutral ramp goes
       near-achromatic at hue 286 instead of cold blue-grey metal at hue 258.
     * the accent moves family: gold (hue 78) -> Apple blue (hue 256).
     * --lift-* no longer opens with `inset 0 1px 0 oklch(1 0 0 / x)`. That one
       declaration is what made every surface read as machined metal. Depth is
       now true Apple elevation: low opacity, large blur, no inset.
     * the radius ladder moves as a whole onto Apple's: 6 / 14 / 18 / 24px and
       a true 980px pill. Every consumer is a var() or a
       calc(outer - var(--bezel)), so the bezel maths still resolves.
   Type scale, spacing, bezel maths and motion are UNCHANGED: this pass is the
   palette / edge / depth / radius layer only.

   No webfont rule of any kind: the system stack only, same as the portal.
   The Bricolage /
   Instrument Sans / Geist Mono .ttf files are left on disk in static/fonts/
   but are no longer referenced by anything.
   ========================================================================== */

:root {
  /* Native form controls, scrollbars and the canvas follow the page, not the
     operating system. A stylesheet declaration beats the <meta name=
     "color-scheme"> equivalent, so this holds even on a page whose meta tag
     has not been updated yet. */
  color-scheme: light;

  /* --- ground + raised surfaces (near-achromatic, hue 286) ---------------
         Cards are WHITE and separated by space and a hairline, not by a
         darker box. surface-3 is a hover / icon-tile tone, not a card fill. */
  --ground:        oklch(1 0 0);             /* #ffffff page ground          */
  --surface-1:     oklch(0.989 0.003 286.4); /* #fbfbfd faint section wash   */
  --surface-2:     oklch(0.971 0.003 286.4); /* #f5f5f7 Apple grey panel     */
  --surface-3:     oklch(0.950 0.003 286.3); /* #eeeef0 icon tile, hover     */
  --wash-down:     oklch(0.969 0.015 22.4);  /* #fff1f0 below-break-even tint*/

  /* --- ink. Three steps, all AA at body size on white. ------------------- */
  --ink-1:         oklch(0.232 0.004 286.1); /* #1d1d1f headings, card names */
  --ink-2:         oklch(0.354 0.004 286.1); /* #424245 secondary            */
  --ink-3:         oklch(0.540 0.008 286.1); /* #6e6e73 descriptions, meta   */

  /* --- edges. edge-control is the only one that identifies a control ----- */
  --edge:          oklch(0.932 0.007 286.3); /* #e8e8ed hairline             */
  --edge-strong:   oklch(0.865 0.007 286.3); /* #d2d2d7 decorative only      */
  --edge-control:  oklch(0.622 0.007 286.2); /* #86868b input + tick borders */

  /* --- brand + signals. ONE accent for the whole product: --brass keeps its
         name and is now the Apple blue, so every reference to it (including
         the focus ring) inherits that for free. jade/red carry state. ----- */
  --brass:         oklch(0.563 0.193 256.2); /* #0071e3 brand, focus, links  */
  --brass-deep:    oklch(0.468 0.164 256.7); /* #0056b3 pressed fill, on mist*/
  --brass-veil:    oklch(0.957 0.018 250.6); /* #e8f2fd quiet blue tint      */
  --jade:          oklch(0.551 0.170 145.7); /* #008a28 live, 4.50:1 on white*/
  /* jade is only 4.11:1 on the pale jade wash, so green TEXT gets this      */
  --jade-deep:     oklch(0.459 0.140 146.0); /* #006b1f green text on a tint */
  --red:           oklch(0.553 0.225 27.3);  /* #d70015 stopped dot, strokes */
  --red-soft:      oklch(0.482 0.197 27.3);  /* #b3000f stopped text         */
  --unknown:       oklch(0.622 0.007 286.2); /* #86868b not-yet-probed dot   */

  /* --- type. No Inter / Roboto / Arial / Helvetica anywhere.
         System stack by design: this portal is demoed offline on a LAN with
         no CDN and no /static mount, and a 73 KB base64 webfont inside a
         Python string is not a trade worth making. ------------------------ */
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display",
                  "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --font-sans:    -apple-system, BlinkMacSystemFont, "SF Pro Text",
                  "Segoe UI Variable Text", "Segoe UI", system-ui, "Noto Sans", sans-serif;
  --font-mono:    ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono",
                  Menlo, "Cascadia Mono", Consolas, monospace;

  /* --- type scale, ratio 1.25-1.27 between adjacent steps ---------------- */
  --fs-sm:   0.78rem;   /* 12.5px  captions, meta                            */
  --fs-base: 0.97rem;   /* 15.5px  body                                      */
  --fs-md:   1.22rem;   /* 19.5px  card titles                               */
  --fs-lg:   1.53rem;   /* 24.5px  cluster headings                          */
  --fs-xl:   1.94rem;   /* 31px    stat figure                               */
  --fs-2xl:  2.44rem;   /* 39px    home wordmark                             */
  --fs-display: clamp(2.44rem, 6.2vw, 3.8rem); /* login wordmark             */
  /* Separate ROLE, not a scale step: tracked uppercase mono micro-label.    */
  --fs-micro: 0.72rem;  /* 11.5px                                            */
  --track-micro: 0.16em;

  /* --- spacing. Deliberately uneven at the top end so bands breathe
         differently from card interiors. ---------------------------------- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;     --sp-7: 3rem;     --sp-8: 4rem;
  --sp-9: 6rem;     --sp-10: 8rem;

  /* --- radii. Moved onto Apple's ladder 2026-09-22: 6 / 14 / 18 / 24px and
         a true 980px pill. Every consumer is written as var() or as
         calc(outer - var(--bezel)), so the double-bezel maths below still
         resolves and no rule needed editing. -------------------------------*/
  --r-sm: 0.375rem; --r-md: 0.875rem; --r-lg: 1.125rem; --r-xl: 1.5rem;
  --r-pill: 980px;
  /* One bezel gap for every double-bezel enclosure, so the inner radius can
     always be written calc(outer - var(--bezel)) and cannot drift. */
  --bezel: 5px;
  /* Fixed z scale. Nothing may invent its own value. */
  --z-base: 0; --z-content: 1; --z-skip: 100;
  /* Dispatch-strip ticks. Stopped is SHORTER as well as red, so state is not
     carried by colour alone. */
  --tick-w: 4px; --tick-h: 18px; --tick-scale-down: 0.61;

  /* --- depth. True Apple elevation: low opacity, large blur, no visible
         edge, no inset highlight. The inset highlight is what made the old
         build read as machined metal and it is deliberately absent. ------- */
  --lift-1: 0 1px 2px oklch(0 0 0 / 0.04);
  --lift-2: 0 1px 3px oklch(0 0 0 / 0.05), 0 8px 20px -10px oklch(0 0 0 / 0.08);
  --lift-3: 0 2px 8px oklch(0 0 0 / 0.05), 0 18px 44px -18px oklch(0 0 0 / 0.12);

  /* --- motion. One easing curve for the whole product (ease-out-expo). --- */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-1: 180ms; --dur-2: 280ms; --dur-3: 560ms;
}

/* ==========================================================================
   APP-LOCAL ROLES -- not part of the shared theme.

   This tool plots a BROADCAST RUNNING ORDER on an instrument, the way Ladder
   plots money zones on one. It therefore needs named roles for the three
   states a show segment can be in. Every one of them is an ALIAS of a colour
   the estate already ships and has already measured. No new hue is minted
   here, and that is the point: "flash sale running" in this tool must be the
   same amber that Ladder calls "thin", Listing Studio calls "watch" and Docket
   calls "v-hold", because all four mean the same thing to a human -- a timed
   state you have to keep an eye on.

   THE ONE COLOUR DECISION WORTH RECORDING. The obvious move for a TikTok tool
   is to reach for TikTok's own red/cyan. Rejected. --red already means STOPPED
   across this estate, and this tool has a genuine stop condition -- a claim
   that is illegal to say on air about a caffeinated food. Spending red on
   decoration would blunt the one place it has to be obeyed. So red appears in
   exactly one component here: the claim-guardrail banner.

   The NOW-marker on the run-sheet spine is chalk (--ink-1), not a signal
   colour, following Ladder's needle rule verbatim: a moving marker that also
   changed colour would say the same thing twice.
   ========================================================================== */
:root {
  /* --- segment / show states ---------------------------------------------
         --timed is #a55900, the estate's standard "watch this, it is on a
         clock" amber. Measured by the estate: 5.21:1 on white, 4.76:1 on its
         own wash. Used for flash sales, countdowns and giveaway windows. */
  --timed:       oklch(0.540 0.150 68);        /* #a55900 on a countdown     */
  --timed-wash:  oklch(0.969 0.020 68);        /* #fef3e7 amber at surface wt*/

  /* A show that has aired and been written up. Same green that means "live"
     everywhere else in the estate; --go is the TEXT weight, which is the only
     one that passes on the pale wash. */
  --go:          var(--jade-deep);             /* #006b1f done / aired       */
  --go-wash:     oklch(0.965 0.035 146);       /* #e5fae6 jade at surface wt */

  /* The claim guardrail. The only stop condition in the product. */
  --stop:        var(--red-soft);              /* #b3000f banned-claim text  */
  --stop-line:   var(--red);                   /* #d70015 strokes, dot       */
  --stop-wash:   var(--wash-down);             /* #fff1f0                    */

  /* The NOW marker and the run-sheet spine. Chalk, never a verdict colour. */
  --onair:       var(--ink-1);
  --spine:       var(--edge-strong);

  --hairline:    1px solid var(--edge);

  /* --- type ROLES (not new scale steps, not new faces) --------------------
         --fs-clock is the minute marker on the spine. It is read at a glance
         from arm's length by someone who is talking to camera, so it sits one
         step above body and is always tabular mono. */
  --fs-clock:    1.06rem;
  /* The one figure allowed above the shared scale, same licence Ladder takes
     for its break-even figure: here it is the show's start time. */
  --fs-figure:   clamp(2.44rem, 4.4vw, 3.05rem);

  --measure:       66ch;   /* body line length, inside the 65-75ch band      */
  --measure-tight: 52ch;   /* prose beside a figure column                   */

  --z-sticky: 10; --z-toast: 30;
}


/* ==========================================================================
   NIGHT MODE  --  opt-in, additive, and OFF by default.   (2026-09-22)

   Nothing above this line changed. Daylight is still the default theme and
   the only theme a first-time visitor ever sees: every declaration below is
   scoped to html[data-theme="dark"], an attribute that ONLY
   static/theme-toggle.js sets, and only after the operator has clicked the
   toggle in the header. There is no prefers-color-scheme rule anywhere in
   this file, and the page's <meta name="color-scheme" content="light"> tag
   is untouched -- this is a manual override, not an automatic one. Clearing
   localStorage returns the tool to Daylight.

   PROVENANCE. Every value below is this tool's own pre-Daylight DARK value,
   copied verbatim from
     rollback_daylight_batch2_2026-09-22_2133/marketplace_pricer/static/tokens.css
   Tokens that the Daylight pass INTRODUCED have no historical dark value;
   each of those is marked DERIVED and says where its value came from.

   WHAT IS DELIBERATELY *NOT* OVERRIDDEN: the type scale, the spacing ladder,
   the radius ladder, --bezel, the z-scale and the motion tokens (--ease,
   --dur-*). A theme switch changes colour and depth; moving the geometry or
   the easing curve on a click would read as a layout bug, not a theme. (The
   dark capture for this batch makes the same call: "non-colour tokens ... are
   theme-invariant: a night toggle should NOT move them".)

   KNOWN LIMIT, not a defect to chase here: the Daylight pass resolved some
   hard-coded colour literals inside app.css to light values. Those specific
   rules stay light-valued under this override, because they are not tokens.
   They are listed per tool in the Part B report.
   ========================================================================== */
html[data-theme="dark"] {
  /* Native controls, form fields, scrollbars and the pre-paint canvas follow
     the page. Set HERE, inside the explicit dark block only -- the <meta>
     tag in every template still says light, so nothing auto-switches. */
  color-scheme: dark;

  --ground:          oklch(0.160 0.011 258);
  --surface-1:       oklch(0.208 0.0125 258);
  --surface-2:       oklch(0.248 0.014 258);
  --surface-3:       oklch(0.290 0.015 258);
  --wash-down:       oklch(0.245 0.038 25);
  --ink-1:           oklch(0.970 0.006 258);
  --ink-2:           oklch(0.800 0.015 258);
  --ink-3:           oklch(0.705 0.018 258);
  --edge:            oklch(0.320 0.016 258);
  --edge-strong:     oklch(0.430 0.020 258);
  --edge-control:    oklch(0.560 0.022 258);
  --brass:           oklch(0.810 0.135 78);
  --brass-deep:      oklch(0.660 0.125 74);
  --jade:            oklch(0.800 0.145 158);
  --red:             oklch(0.690 0.190 25);
  --red-soft:        oklch(0.760 0.138 27);
  --unknown:         oklch(0.480 0.018 258);
  --lift-1:          inset 0 1px 0 oklch(1 0 0 / 0.055);
  --lift-2:          inset 0 1px 0 oklch(1 0 0 / 0.085), 0 1px 2px oklch(0 0 0 / 0.35);
  --lift-3:          inset 0 1px 0 oklch(1 0 0 / 0.10), 0 12px 28px -12px oklch(0 0 0 / 0.65);
  /* App-local roles, dark values. Same provenance rule as above: each one is
     the pre-Daylight dark value of the estate token it aliases in light. */
  --go:              var(--jade);
  --go-wash:         oklch(0.283 0.048 158);
  --timed:           var(--brass);
  --timed-wash:      oklch(0.288 0.050 78);
  --stop:            var(--red-soft);
  --stop-line:       var(--red);
  --stop-wash:       var(--wash-down);
  --onair:           var(--ink-1);
  --spine:           var(--edge-strong);

  /* Tokens the Daylight pass introduced: no historical dark value exists,
     so each of these is derived and says from what. */
  /* DERIVED: Daylight-only token. The family's dark brass wash, the
     value the pre-Daylight themes used for every brass tint. */
  --brass-veil:      oklch(0.288 0.050 78);
  /* DERIVED: Daylight-only token. Dark had ONE green weight, --jade, and
     it was the text weight. */
  --jade-deep:       oklch(0.800 0.145 158);
}

/* --------------------------------------------------------------------------
   The toggle itself. An icon button, quiet enough to ignore: no fill, one
   hairline, and it shows the state you would move TO -- sun while you are in
   the dark, moon while you are in the light. Both glyphs are aria-hidden;
   the button's aria-label and aria-pressed carry the meaning, and
   theme-toggle.js rewrites both on every flip.

   No inline style and no inline handler anywhere: this app ships
   `style-src 'self'; script-src 'self'` with no nonce.
   -------------------------------------------------------------------------- */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  padding: 0.35rem 0.5rem;
  background: none;
  border: 1px solid var(--edge-control);
  border-radius: var(--r-md);
  color: inherit;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: color 160ms ease-out, border-color 160ms ease-out;
}
.theme-toggle:hover { color: var(--brass); border-color: var(--brass); }
.theme-toggle .tt-moon { display: none; }
html[data-theme="dark"] .theme-toggle .tt-sun  { display: none; }
html[data-theme="dark"] .theme-toggle .tt-moon { display: inline; }

/* Touch: a 34px control is fine for a mouse and too small for a thumb. */
@media (pointer: coarse) {
  .theme-toggle { min-width: 44px; min-height: 44px; }
}

/* The sign-in pages are a centred plate with no header to hang a control on,
   so there the toggle pins itself to the top corner instead. It is opaque so
   it never sits on top of the gate artwork. */
.theme-toggle--float {
  position: fixed;
  top: var(--sp-4);
  right: var(--sp-4);
  z-index: 50;
  background: var(--surface-1);
}
