/* ui/tokens.css */
/* Design tokens (plan section 3). Values are the engine pages' (planner "Tokens", scenes "Tokens", topshine
   static/app.css :root) under semantic names, so a dark set can be added later without touching a component. */
@font-face { font-family: "Source Serif 4"; src: url(/assets/fonts/source-serif-4-latin-standard-normal.woff2) format("woff2"); font-weight: 200 900; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url(/assets/fonts/hanken-grotesk-latin-wght-normal.woff2) format("woff2"); font-weight: 100 900; font-display: swap; }

:root {
  color-scheme: light;

  /* 3.1 Colour */
  --page: oklch(99.2% 0.0026 286);          /* #fcfcfe: the progress concept's near-white, flat */
  --page-deep: oklch(95.4% 0.008 286);      /* wells, the timeline track: #f0f0f6, reads against the page */
  --surface: oklch(100% 0 0);
  --violet-mark: oklch(60% 0.22 287);        /* the logo's star: lighter than the action violet (#7f60fa, the waitlist concept's) */
  --wash: oklch(97.6% 0.006 300);
  --ink: oklch(21% 0.014 285);
  --ink-2: oklch(38% 0.014 285);
  --muted: oklch(53% 0.013 285);
  --faint: oklch(68% 0.011 285);
  --card-edge: oklch(96.4% 0.0058 265);       /* a card's 1 px edge in the app (#f1f3f7); the public pages' own is in .public */
  --hair: oklch(91.5% 0.008 286);
  --hair-2: oklch(87% 0.01 286);
  --violet: oklch(54% 0.24 286);            /* the accent: the concept's blue-violet */
  --violet-ink: oklch(45% 0.27 273);
  --violet-soft: oklch(95% 0.03 286);
  --violet-ring: oklch(68% 0.17 287);        /* lighter than the action violet: the spend bar's far end */
  --branch: oklch(66% 0.17 287);
  --mint: oklch(87% 0.085 160);
  --mint-deep: oklch(56% 0.11 160);
  --mint-ink: oklch(38% 0.08 160);
  --mint-soft: oklch(96% 0.035 160);
  --btn: oklch(23% 0.025 170);
  --btn-hover: oklch(27% 0.03 170);
  --bad: oklch(54% 0.16 25);
  --bad-soft: oklch(96% 0.025 25);
  --warn: oklch(77% 0.14 60);
  --warn-ink: oklch(47% 0.11 58);
  --warn-soft: oklch(96% 0.04 82);
  --film: oklch(17% 0.012 285);

  /* Phases of a session (timeline segments, ring arcs) */
  --ph-start: oklch(76% 0.11 282);
  --ph-download: var(--mint);
  --ph-load: oklch(87% 0.12 90);
  --ph-clips: oklch(83% 0.085 330);
  --ph-clips-deep: oklch(64% 0.17 330);     /* the clips' orchid, deep: the H3 model dot, the end of the ring's clips arc */
  --ph-spare: repeating-linear-gradient(135deg, var(--hair-2) 0 1.5px, var(--page-deep) 1.5px 6px);

  /* Plan hues: the mark on group headers and rows, in session order, then repeating */
  --plan-1: oklch(83% 0.085 330);
  --plan-2: oklch(84% 0.07 200);
  --plan-3: oklch(87% 0.12 90);
  --plan-4: oklch(76% 0.11 282);

  /* State colours */
  --st-made: var(--mint-deep);
  --st-running: var(--violet);
  --st-queued: var(--faint);
  --st-notmade: var(--bad);
  --st-cancelled: var(--muted);

  /* 3.2 Type */
  --serif: "Source Serif 4", "Iowan Old Style", Georgia, serif;
  --sans: "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;
  /* Roles: the serif is for the page title and for money figures; every other heading and name takes the sans */
  --font-display: var(--serif);
  --font-figure: var(--serif);
  --font-heading: var(--sans);
  --t-12: 12px; --t-13: 13px; --t-15: 15px; --t-17: 17px; --t-20: 20px; --t-22: 22px;
  /* The card heading size (Session timeline, Live preview, plan titles, Cost breakdown, sheet titles): the concept's titles measure a cap height of 12 px at 1536 wide, about 16 px type at 1440 */
  --t-card-heading: 16px;
  --t-28: 28px; --t-34: 34px; --t-44: 44px; --t-56: 56px; --t-72: 72px;
  /* The public hero's display (operator, 2026-10-30; the waitlist home): the sans, heavy and tight, 56 px on a 1.066 line
     (the concept's 59.7 px pitch). The serif display stays for app titles and money. */
  --font-display-sans: var(--sans);
  --t-display-sans: var(--t-56);
  --w-display-sans: 700;
  --ls-display-sans: -0.06em;
  --lh-display-sans: 1.066;

  /* 3.3 Space, radius, elevation */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-7: 32px; --s-8: 40px; --s-9: 56px; --s-10: 72px;
  /* The page gutter (the edge to the first card) and the card gap (between cards, in a row and between rows): the gap is always the smaller */
  --gutter: clamp(16px, 1.6vw, 23px);
  --gap: clamp(12px, 0.97vw, 14px);
  --r-page: 10px; --r-card: 9px; --r-ctl: 6px; --r-poster: 2px; --r-pill: 999px;   /* measured on the concepts (scaled to 1440): page card 9.8, clip card 8.9, button 5.6, poster about 2 */
  --pad-card: 20px; --pad-inner: 10px;   /* card padding: page cards 19–21, clip cards 10 */
  --shadow: 0 0 0 1px var(--card-edge), 0 1px 2px oklch(25% 0.02 285 / 0.03), 0 12px 32px -16px oklch(25% 0.03 285 / 0.10);
  --shadow-sm: 0 0 0 1px var(--card-edge), 0 1px 2px oklch(25% 0.02 285 / 0.03), 0 4px 14px -8px oklch(25% 0.03 285 / 0.09);
  --shadow-lift: 0 0 0 1px oklch(25% 0.02 285 / 0.06), 0 24px 60px -20px oklch(25% 0.03 285 / 0.28);
  --glow-mint: radial-gradient(closest-side, color-mix(in oklch, var(--mint) 70%, transparent), color-mix(in oklch, var(--mint) 22%, transparent) 55%, transparent);
  --glow-btn: 0 0 0 1px oklch(70% 0.12 160 / 0.35), 0 10px 26px -10px oklch(60% 0.14 160 / 0.6), 0 14px 34px -18px color-mix(in oklch, var(--violet) 45%, transparent), inset 0 1px 0 oklch(100% 0 0 / 0.08);
  --content: 1480px;
  --create-w: 192px;   /* the planner's floating Create; the scene diagram's row leaves this much room at its end */
  /* The progress screen's timeline card: a fixed height, so no state change resizes it */
  --h-timeline: 184px;

  /* 3.4 Motion: every duration is multiplied by --motion-scale (5 in slow motion, 0 under reduced motion) */
  --motion-scale: 1;
  --d-tap: calc(80ms * var(--motion-scale));
  --d-quick: calc(160ms * var(--motion-scale));
  --d-move: calc(240ms * var(--motion-scale));
  --d-slow: calc(360ms * var(--motion-scale));
  --d-fan: calc(480ms * var(--motion-scale));
  --d-fade: calc(120ms * var(--fade-scale, var(--motion-scale)));
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-spring: var(--ease-out);
}
@supports (animation-timing-function: linear(0, 1)) {
  :root { --ease-spring: linear(0, 0.054, 0.177, 0.328, 0.480, 0.618, 0.734, 0.826, 0.896, 0.946, 0.980, 1.001, 1.013, 1.019, 1.020, 1.019, 1.016, 1.013, 1.010, 1.007, 1.005, 1.003, 1.002, 1.001, 1); }
}
@media (max-width: 599px) { :root { --pad-card: 16px; } }
@media (max-width: 599px) { :root { --h-timeline: 124px; } }
/* Reduced motion: movement takes no time; opacity crossfades keep --d-fade */
@media (prefers-reduced-motion: reduce) { :root { --motion-scale: 0 !important; --fade-scale: 1; } }
html[data-motion="reduce"] { --motion-scale: 0 !important; --fade-scale: 1; }

/* The public pages' theme: on a page whose body is .public (the
   waitlist pages) the concept's blue-violet, its grey page and its blue-tinted inks; the app keeps its own.
   --violet-deep is the film titles' deep violet. */
.public { --violet: oklch(54% 0.24 286); --violet-ink: oklch(45% 0.27 273); --violet-soft: oklch(95% 0.03 286); --violet-deep: oklch(23% 0.15 269);
  --page: oklch(98% 0.003 286); --ink: oklch(17% 0.046 271); --ink-2: oklch(34% 0.05 268); --muted: oklch(49% 0.04 276);
  /* an off-white with the page's hue (the concept's cards and tiles are #fafafc-#fcfcfe), so a mix with --surface keeps
     the violet's hue (hue 0 pulled it toward pink); the placeholder grey is blue-tinted; the chosen tile's ring is
     lighter than the action violet */
  --surface: oklch(99.2% 0.002 286); --faint: oklch(72% 0.023 277); --violet-ring: oklch(68% 0.17 287);
  /* a card's edge is the concept's #eaebf1 inside a soft halo about 7 px wide on the form's card (the app's
     --card-edge is the page just outside it) */
  --shadow: 0 0 0 1px oklch(94% 0.008 280), 0 0 7px oklch(25% 0.03 285 / 0.07), 0 12px 32px -16px oklch(25% 0.03 285 / 0.10);
  --shadow-sm: 0 0 0 1px oklch(94% 0.008 280), 0 1px 2px oklch(25% 0.02 285 / 0.03), 0 4px 14px -8px oklch(25% 0.03 285 / 0.09); }

/* ui/base.css */
/* Reset, type scale, page shell, focus ring, reduced motion, the digit roll and the copy-key tints. */
*, *::before, *::after { box-sizing: border-box; }
html { overflow-x: clip; background: var(--page); color: var(--ink); font-family: var(--sans); font-size: var(--t-15); line-height: 1.5;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; text-rendering: optimizeLegibility; }
body { margin: 0; min-height: 100dvh; overflow-x: clip; background: var(--page); }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
h1, h2, h3 { text-wrap: balance; font-weight: 600; }
p { text-wrap: pretty; }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
a { color: var(--violet-ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
img, video, svg { display: block; max-width: 100%; }
:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; border-radius: 4px; }
[hidden] { display: none !important; }

.serif { font-family: var(--font-display); font-optical-sizing: auto; }
.num, .roll, .fig { font-variant-numeric: tabular-nums lining-nums; }
.fig { font-family: var(--font-figure); font-weight: 600; font-optical-sizing: auto; }
.small { font-size: var(--t-13); line-height: 1.4; color: var(--muted); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Type scale */
.t-display { font-family: var(--font-display); font-optical-sizing: auto; font-weight: 600; letter-spacing: -0.02em; line-height: 1.04; font-size: var(--t-34); }
.t-title { font-family: var(--font-heading); font-optical-sizing: auto; font-weight: 650; letter-spacing: -0.005em; line-height: 1.25; font-size: var(--t-card-heading); }
@media (min-width: 900px) { .t-display { font-size: var(--t-56); } }
/* The public hero's display: the sans, heavy and tight (tokens --t-display-sans and its weight, tracking and line) */
.t-display-sans { font-family: var(--font-display-sans); font-weight: var(--w-display-sans); letter-spacing: var(--ls-display-sans); line-height: var(--lh-display-sans); font-size: var(--t-34); }
@media (min-width: 900px) { .t-display-sans { font-size: var(--t-display-sans); } }

/* Page shell */
.page { position: relative; width: 100%; max-width: var(--content); margin: 0 auto; padding: 0 var(--gutter); }
.card { position: relative; background: var(--surface); border-radius: var(--r-page); box-shadow: var(--shadow); }
.card.inner { border-radius: var(--r-card); box-shadow: var(--shadow-sm); }
.card-pad { padding: var(--pad-card); }

/* Sideways scrollers (declared with data-scroll-x so the check tool allows them) */
[data-scroll-x] { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: thin; scrollbar-color: var(--hair-2) transparent; }
[data-scroll-x] > * { scroll-snap-align: start; }

/* Digit roll (M5): the real value stays in the element's text; the overlay is decoration. */
.roll { position: relative; display: inline-block; font-kerning: none; white-space: nowrap; }
.roll.rolling { -webkit-text-fill-color: transparent; }
.roll-ov { position: absolute; left: 0; top: 0; display: inline-flex; white-space: pre; -webkit-text-fill-color: currentcolor; pointer-events: none; user-select: none; -webkit-user-select: none; }
.rd { display: inline-flex; flex-direction: column; height: 1lh; overflow: hidden; }
.rd > span { flex: none; height: 1lh; }
.rd.up > span { animation: roll-up calc(250ms * var(--motion-scale)) var(--ease-out) both; }
.rd.down > span { animation: roll-down calc(250ms * var(--motion-scale)) var(--ease-out) both; }
@keyframes roll-up { from { transform: translateY(0); } to { transform: translateY(-100%); } }
@keyframes roll-down { from { transform: translateY(-100%); } to { transform: translateY(0); } }

/* Copy keys (playground switch): new strings amber, BYOT violet, the builder's open asks rose; the key shows on hover */
html[data-copykeys] [data-st="new"] { background: oklch(93% 0.09 85 / 0.75); box-shadow: 0 0 0 2px oklch(93% 0.09 85 / 0.75); border-radius: 3px; }
html[data-copykeys] [data-st="byot"] { background: oklch(91% 0.06 286 / 0.8); box-shadow: 0 0 0 2px oklch(91% 0.06 286 / 0.8); border-radius: 3px; }
html[data-copykeys] [data-st="ask"] { background: oklch(91% 0.07 15 / 0.8); box-shadow: 0 0 0 2px oklch(91% 0.07 15 / 0.8); border-radius: 3px; }

/* A crossfading text's old copy (TS.motion.crossText) */
.ts-ghost { position: absolute !important; left: 0; top: 0; bottom: 0; margin: 0 !important; background: transparent !important; box-shadow: none !important; pointer-events: none; }

/* Shared keyframes */
@keyframes ts-fade-in { from { opacity: 0; } }
@keyframes ts-rise-in { from { opacity: 0; translate: 0 6px; } }
@keyframes ts-drop-in { from { opacity: 0; translate: 0 -6px; } }
@keyframes ts-spin { to { rotate: 360deg; } }

/* ui/c/button.css */
/* Button (.btn with .primary, .accent, .quiet, .danger-quiet, .icon, .wide; .busy while it sends). CSS only.
   .accent is the violet action of a public page's form (the waitlist's Join).
   Every button is at least 44 px high. A busy button keeps its width: its icon gives way to a small spinner, or
   with no icon the label fades under a centred one (M13). */
.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 18px;
  border-radius: var(--r-ctl); font-size: var(--t-15); font-weight: 600; line-height: 1.2; color: var(--ink); background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hair-2); white-space: nowrap; text-decoration: none; user-select: none; -webkit-user-select: none;
  transition: scale var(--d-tap) var(--ease-out), background-color var(--d-quick) var(--ease-out), box-shadow var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.btn > .i { flex: none; width: 18px; height: 18px; }
.btn:active:not([disabled]):not([aria-disabled="true"]) { scale: 0.98; }
@media (hover: hover) { .btn:hover { box-shadow: inset 0 0 0 1px var(--faint); } }

.btn.primary { background: var(--btn); color: oklch(98% 0.01 160); box-shadow: var(--glow-btn); }
@media (hover: hover) { .btn.primary:hover { background: var(--btn-hover); box-shadow: var(--glow-btn); } }
.btn.accent { background: var(--violet); color: oklch(99% 0.005 305); box-shadow: none; font-weight: 500; }
@media (hover: hover) { .btn.accent:hover { background: color-mix(in oklch, var(--violet) 88%, var(--violet-ink)); box-shadow: none; } }
.btn.accent[disabled], .btn.accent[aria-disabled="true"] { box-shadow: none; }
.btn.quiet { background: transparent; box-shadow: none; color: var(--ink-2); padding: 0 12px; }
@media (hover: hover) { .btn.quiet:hover { background: var(--page-deep); color: var(--ink); box-shadow: none; } }
.btn.danger-quiet { color: var(--bad); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--bad) 32%, transparent); }
@media (hover: hover) { .btn.danger-quiet:hover { background: var(--bad-soft); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--bad) 50%, transparent); } }
.btn.icon { flex: none; width: 44px; padding: 0; border-radius: var(--r-ctl); }
.btn.icon.round { border-radius: 50%; }
.btn.small { font-size: var(--t-13); padding: 0 14px; }
/* The phone's one full-width action, fixed at the bottom (picks-phone "Make film" bar) */
.btn.wide { width: 100%; min-height: 56px; border-radius: var(--r-card); font-size: var(--t-17); letter-spacing: -0.005em; }
/* The public form's full-width violet action (the waitlist's Join, after waitlist-gpt-1): 50 high, its arrow after the
   label */
.btn.accent.wide { min-height: 50px; gap: 16px; border-radius: var(--r-ctl); font-size: var(--t-17); }
.btn.accent.wide > .i { width: 18px; height: 18px; }
/* Its fill is a faint vertical gradient with a darker 1 px foot (measured on the concept) */
.btn.accent.wide { background-image: linear-gradient(oklch(55% 0.24 287), oklch(52% 0.23 285)); box-shadow: inset 0 -1px 0 oklch(47% 0.24 283); }
@media (hover: hover) { .btn.accent.wide:hover { background-image: linear-gradient(color-mix(in oklch, oklch(55% 0.24 287) 88%, var(--violet-ink)), color-mix(in oklch, oklch(52% 0.23 285) 88%, var(--violet-ink))); box-shadow: inset 0 -1px 0 oklch(47% 0.24 283); } }
@media (max-width: 599px) { .btn.accent.wide { min-height: 56px; gap: 14px; border-radius: var(--r-card); font-size: var(--t-17); } }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.btn.primary[disabled], .btn.primary[aria-disabled="true"] { box-shadow: none; }

.btn.busy { pointer-events: none; }
.btn.busy > .i:first-child { visibility: hidden; }
.btn.busy::after { content: ""; position: absolute; width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; opacity: 0.85; }
.btn.busy:has(> .i:first-child)::after { left: 19px; }
.btn.busy:not(:has(> .i:first-child)) { color: transparent; }
.btn.primary.busy:not(:has(> .i:first-child))::after { border-color: oklch(98% 0.01 160); border-right-color: transparent; }
.btn.busy:not(:has(> .i:first-child))::after { border-color: var(--ink); border-right-color: transparent; }
.btn.primary.busy:not(:has(> .i:first-child))::after { border-color: oklch(98% 0.01 160); border-right-color: transparent; }
.btn.accent.busy:not(:has(> .i:first-child))::after { border-color: oklch(99% 0.005 305); border-right-color: transparent; }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .btn.busy::after { animation: ts-spin calc(800ms * max(var(--motion-scale), 1)) linear infinite; }
}

/* A bar of actions: wraps, and on a phone the .wide action takes the row */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

/* ui/c/chip.css */
/* Chip and badge (.chip with a state class; .badge for a page's state). CSS only.
   Clip states: queued, running, made, not_made, cancelled. Session states: queued, starting, running, finishing, done,
   done_partial, failed, cancelled. Kinds: .kind (Scene, Comparison). */
.chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--r-pill); font-size: 12.5px; font-weight: 600;
  line-height: 1; white-space: nowrap; overflow: hidden; background: var(--page-deep); color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums;
  transition: background-color var(--d-move) var(--ease-out), color var(--d-move) var(--ease-out); }
.chip.st::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.chip.queued { background: var(--wash); color: var(--muted); box-shadow: inset 0 0 0 1px var(--hair); }
.chip.running, .chip.starting, .chip.finishing { background: var(--violet-soft); color: var(--violet-ink); }
.chip.made, .chip.done { background: var(--mint-soft); color: var(--mint-ink); }
.chip.not_made, .chip.failed { background: var(--bad-soft); color: var(--bad); }
.chip.done_partial { background: var(--warn-soft); color: var(--warn-ink); }
.chip.cancelled { background: var(--page-deep); color: var(--muted); }
.chip.kind { background: var(--surface); color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--hair-2); }
.chip.added { background: var(--surface); color: var(--violet-ink); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 40%, transparent); }
.chip.agent { background: var(--violet-soft); color: var(--violet-ink); }
.chip.count { background: var(--violet-soft); color: var(--violet-ink); }

/* The page's state badge, beside a title. .outline: page-coloured with a hairline edge and ink text (a public hero's
   pill, the waitlist's "Made for filmmakers") */
.badge { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border-radius: var(--r-pill); font-size: var(--t-13); font-weight: 600;
  white-space: nowrap; background: var(--page-deep); color: var(--ink-2); }
.badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.badge.running, .badge.starting, .badge.finishing, .badge.live { background: var(--violet-soft); color: var(--violet-ink); }
.badge.done { background: var(--mint-soft); color: var(--mint-ink); }
.badge.done_partial { background: var(--warn-soft); color: var(--warn-ink); }
.badge.failed { background: var(--bad-soft); color: var(--bad); }
.badge.queued, .badge.cancelled { background: var(--page-deep); color: var(--muted); }

/* The live dot (beside "Spent so far" and the live line): mint, with a slow soft glow while a session runs (3.6 s).
   .on turns the glow on; nothing moves under reduced motion. */
.live-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--mint-deep); box-shadow: 0 0 3px 0 color-mix(in oklch, var(--mint-deep) 25%, transparent); }
@keyframes live-glow {
  0%, 100% { box-shadow: 0 0 3px 0 color-mix(in oklch, var(--mint-deep) 25%, transparent), 0 0 0 0 color-mix(in oklch, var(--mint) 0%, transparent); }
  50% { box-shadow: 0 0 9px 2px color-mix(in oklch, var(--mint-deep) 50%, transparent), 0 0 0 5px color-mix(in oklch, var(--mint) 40%, transparent); }
}
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .live-dot.on { animation: live-glow calc(3.6s * max(var(--motion-scale), 1)) ease-in-out infinite; }
}
.live-dot.off { background: var(--faint); box-shadow: none; transition: background-color var(--d-slow) var(--ease-out), box-shadow var(--d-slow) var(--ease-out); }
.live-dot.off.done { background: var(--mint-deep); opacity: 0.55; }
.badge.outline { height: 37px; gap: 9px; padding: 0 17px; background: var(--page); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--hair); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.12em; }
.badge.outline::before { width: 10px; height: 10px; background: var(--violet); }

/* ui/c/money.css */
/* Money row (.money-row: label left, figure right, an optional (i)) and stat (.stat: a label over a large figure).
   CSS only. Figures are the serif with tabular lining numerals; .key is the screen's key amount with the mint glow. */
.money-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-height: 32px; padding: 4px 0; font-size: var(--t-15); }
.money-row + .money-row { border-top: 1px solid var(--hair); }
.money-row .l { display: inline-flex; align-items: center; gap: 2px; color: var(--ink-2); min-width: 0; }
.money-row .v { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-17); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.money-row.em .l { color: var(--ink); font-weight: 600; }
.money-row.em .v { font-size: var(--t-22); }
.money-row.struck .v { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.money-row.back .v { color: var(--mint-ink); }

.stat { display: grid; gap: 2px; align-content: start; min-width: 0; }
.stat .l { display: inline-flex; align-items: center; gap: 2px; min-height: 22px; font-size: var(--t-13); font-weight: 500; color: var(--muted); }
.stat .v { font-family: var(--font-figure); font-optical-sizing: auto; font-weight: 600; font-size: var(--t-28); line-height: 1.05; letter-spacing: -0.01em; font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.stat.small-v .v { font-size: var(--t-22); }
.stat.key { position: relative; isolation: isolate; }
.stat.key .v { position: relative; width: max-content; font-size: var(--t-44); letter-spacing: -0.02em; }
.stat.key .v::before { content: ""; position: absolute; z-index: -1; width: 200px; height: 200px; right: -90px; top: 50%; translate: 0 -54%; border-radius: 50%; background: var(--glow-mint); pointer-events: none; }
@media (min-width: 900px) { .stat.key .v { font-size: var(--t-56); } }
.stats { display: flex; flex-wrap: wrap; gap: 16px 32px; }

/* ui/c/field.css */
/* Field (.field: text, number, textarea, checkbox, switch). CSS only. States: rest, focus, invalid with its message,
   saved (its saved line), not saved (BYOT C3). .pub: a public page's form (the waitlist's), its label and field in
   the concept's sizes. */
.field { display: grid; gap: 6px; min-width: 0; }
.field > .fl { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); }
.field > .fh { font-size: var(--t-13); color: var(--muted); max-width: 62ch; }
.field input:not([type=checkbox]), .field textarea { width: 100%; min-height: 48px; padding: 11px 14px; border: 0; border-radius: var(--r-ctl);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2); font-size: var(--t-15); color: var(--ink);
  transition: box-shadow var(--d-quick) var(--ease-out); }
.field textarea { min-height: 96px; resize: vertical; line-height: 1.5; field-sizing: content; max-height: 12lh; }
.field input[type=number] { font-variant-numeric: tabular-nums lining-nums; max-width: 180px; }
.field input:focus, .field textarea:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 4px var(--violet-soft); }
.field.invalid input, .field.invalid textarea { box-shadow: inset 0 0 0 1.5px var(--bad); }
.field .fmsg { display: flex; align-items: flex-start; gap: 6px; font-size: var(--t-13); font-weight: 500; }
.field .fmsg .i { flex: none; width: 16px; height: 16px; margin-top: 1px; }
.field.invalid .fmsg { color: var(--bad); }
.field.saved .fmsg { color: var(--mint-ink); }
.field.unsaved .fmsg { color: var(--warn-ink); }
.field-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }

/* Checkbox and switch: the whole row is the 44 px target */
.check { position: relative; display: flex; align-items: center; gap: 12px; min-height: 44px; cursor: pointer; font-size: var(--t-15); }
.check input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.check .box { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 7px; background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair-2);
  transition: background-color var(--d-tap), box-shadow var(--d-tap); }
.check .box .i { width: 15px; height: 15px; color: #fff; opacity: 0; scale: 0.6; transition: opacity var(--d-tap), scale var(--d-quick) var(--ease-spring); stroke-width: 2.4; }
.check input:checked + .box { background: var(--violet); box-shadow: none; }
.check input:checked + .box .i { opacity: 1; scale: 1; }
.check input:focus-visible + .box { outline: 2px solid var(--violet); outline-offset: 2px; }
.check .sw { flex: none; position: relative; width: 40px; height: 24px; border-radius: 999px; background: var(--hair-2); transition: background-color var(--d-quick); }
.check .sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px oklch(25% 0.02 285 / 0.25);
  transition: translate var(--d-move) var(--ease-spring); }
.check input:checked + .sw { background: var(--violet); }
.check input:checked + .sw::after { translate: 16px 0; }
.check input:focus-visible + .sw { outline: 2px solid var(--violet); outline-offset: 2px; }
.checks { display: grid; gap: 0; }
/* .pub: a public page's form (the waitlist's, after waitlist-gpt-1): label 15 in ink, field 47 high, text inset 19, a
   --hair edge */
.field.pub { gap: 6px; }
.field.pub > .fl { font-size: var(--t-15); font-weight: 500; color: var(--ink); }
.field.pub input:not([type=checkbox]) { min-height: 47px; padding: 0 19px; font-size: var(--t-15); box-shadow: inset 0 0 0 1px var(--hair); }
.field.pub input::placeholder { color: var(--faint); }
.field.pub input:focus { box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 4px var(--violet-soft); }
.field.pub.invalid input { box-shadow: inset 0 0 0 1.5px var(--bad); }
/* A switch beside its label and help line (TS.switchRow): the shot editor's and the editor box's Add the characters */
.swr { display: flex; align-items: flex-start; gap: 12px; }
.swr-b { position: relative; flex: none; width: 44px; height: 44px; margin: -11px -2px -11px -2px; display: grid; place-items: center; }
.swr-k { position: relative; width: 40px; height: 24px; border-radius: 999px; background: var(--hair-2); transition: background-color var(--d-quick); }
.swr-k::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px oklch(25% 0.02 285 / 0.25);
  transition: translate var(--d-move) var(--ease-spring); }
.swr-b[aria-checked="true"] .swr-k { background: var(--violet); }
.swr-b[aria-checked="true"] .swr-k::after { translate: 16px 0; }
.swr-b[disabled] { opacity: 0.5; cursor: default; }
.swr-b:focus-visible { outline: none; }
.swr-b:focus-visible .swr-k { outline: 2px solid var(--violet); outline-offset: 2px; }
.swr-t { display: grid; gap: 1px; min-width: 0; font-size: var(--t-15); }
.swr-t b { font-weight: 600; color: var(--ink); }
.swr-h { font-size: 12.5px; color: var(--muted); }

/* ui/c/seg.css */
/* Segmented filter (.seg, one option on). CSS only: radio inputs in labels, so it works with no script.
   It scrolls sideways inside itself when the options are wider than a phone; .wrap wraps them instead; .tiles shows
   each option as a tile with its icon over its label. */
.seg { display: inline-flex; max-width: 100%; gap: 2px; padding: 4px; border-radius: var(--r-card); background: var(--page-deep); }
.seg label { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 16px; border-radius: var(--r-ctl);
  font-size: var(--t-15); font-weight: 600; color: var(--ink-2); white-space: nowrap; cursor: pointer;
  transition: background-color var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out), box-shadow var(--d-quick) var(--ease-out); }
.seg input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.seg label:has(input:checked) { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.seg label:has(input:focus-visible) { outline: 2px solid var(--violet); outline-offset: 1px; }
@media (hover: hover) { .seg label:not(:has(input:checked)):hover { color: var(--ink); } }
/* .wrap: a choice inside a form (the waitlist's "What will you make?"): under 600 px the options wrap into two equal
   columns in place of scrolling, so every option shows at once */
@media (max-width: 599px) {
  .seg.wrap { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; }
  .seg.wrap label { padding: 0 10px; white-space: normal; text-align: center; line-height: 1.2; }
}

/* .tiles: a few options as tiles in a row, an icon over each label (the waitlist's "What will you make?", after
   waitlist-gpt-1): 97 high with a 34 px icon, 18 px from the tile's top; the chosen tile takes a
   lighter violet outline (--violet-ring) and a faint violet fill. Under 600 px the tiles wrap into two columns. */
.seg.tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; width: 100%; padding: 0; background: none; border-radius: 0; }
.seg.tiles label { flex-direction: column; gap: 10px; min-height: 97px; padding: 18px 8px 12px; border-radius: var(--r-card); background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair);
  font-size: var(--t-13); font-weight: 500; line-height: 1.2; color: var(--ink-2); white-space: normal; text-align: center; }
.seg.tiles label .i { width: 34px; height: 34px; color: var(--ink-2); stroke-width: 1.3; transition: color var(--d-quick) var(--ease-out), scale var(--d-move) var(--ease-spring); }
.seg.tiles label:has(input:checked) { background: color-mix(in oklch, var(--violet-soft) 30%, var(--surface)); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--violet-ring, var(--violet)); }
.seg.tiles label:has(input:checked) .i { color: var(--violet); }
@media (hover: hover) { .seg.tiles label:not(:has(input:checked)):hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--faint); } }
@media (max-width: 599px) {
  .seg.tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .seg.tiles label { gap: 8px; min-height: 80px; padding: 12px 8px; font-size: var(--t-15); }
  .seg.tiles label .i { width: 24px; height: 24px; }
}

/* ui/c/page-head.css */
/* Page title block (.page-head): an optional back link, the title, its kind chip and state badge, a lead line and
   the page's actions. CSS only. No eyebrow label above the title. */
.page-head { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 24px 0 20px; }
.page-head .ph-row { display: flex; align-items: center; gap: 4px 12px; flex-wrap: wrap; min-width: 0; }
.page-head .ph-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.page-head h1 { overflow-wrap: anywhere; }
.page-head .back { margin-left: -10px; }
.page-head .back .i { width: 22px; height: 22px; }
.page-head .ph-lead { font-size: var(--t-17); color: var(--ink-2); max-width: 68ch; }
.page-head .ph-act { display: flex; flex-wrap: wrap; gap: 10px; }
@media (min-width: 900px) {
  .page-head { grid-template-columns: minmax(0, 1fr) auto; align-items: end; padding: 32px 0 24px; }
  .page-head .ph-act { justify-content: flex-end; }
}

/* ui/c/page-top.css */
/* Page top (TS.pageTop, page-top.js): the plan pages' header on the page, with no card (the operator's concept): the
   back link, the title row with the previous and next arrows, the line under the title, the thin divider before the
   money, and the plan's photo in the page's top-right corner behind the nav bar. The screen sets --h-top (the title
   area's height) and places the parts in its grid. */
.ptop-title { position: relative; z-index: 3; display: grid; align-content: end; height: var(--h-top); padding-bottom: 16px; min-width: 0; container-type: inline-size; }
.ptop-div { justify-self: center; align-self: center; width: 1px; height: 136px; background: var(--hair-2); }
/* The plan's photo: the page's top-right corner, behind the header row (64 px), down to the row under the title. A mask melts
   it into the page on its left and bottom edges (eased stops, as the progress screen's picture), so it blends with any page
   colour. From 1100 px it starts right of the money (about x 950 at 1440), so the key amount and its glow sit on clean
   page; a short fade on its left (solid from 22 % of its width), opaque to 60 % of its height. .ptop-over is the same box,
   unmasked, for what is drawn across the photo (the progress screen's light trail). */
.ptop-photo, .ptop-over { position: absolute; z-index: 0; top: 0; right: 0; width: min(34vw, 490px); height: 306px; overflow: hidden; pointer-events: none; }
.ptop-photo { --fade-x: linear-gradient(to right, transparent 0%, rgb(0 0 0 / 0.1) 4.4%, rgb(0 0 0 / 0.34) 9.4%, rgb(0 0 0 / 0.63) 14.3%, rgb(0 0 0 / 0.88) 18.7%, #000 22%);
  --fade-y: linear-gradient(to bottom, #000 0%, #000 60%, rgb(0 0 0 / 0.81) 70%, rgb(0 0 0 / 0.5) 80%, rgb(0 0 0 / 0.2) 90%, transparent 100%);
  -webkit-mask-image: var(--fade-x), var(--fade-y); mask-image: var(--fade-x), var(--fade-y); -webkit-mask-composite: source-in; mask-composite: intersect; }
/* the progress screen's photo is narrower, so the spend card's last column clears its fade */
@media (min-width: 1280px) { body:has(.pr-grid) :is(.ptop-photo, .ptop-over) { width: min(27vw, 390px); } }
.ptop-photo img, .ptop-pic img { -webkit-user-drag: none; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 55% 45%; }
.ptop-photo img.leaving, .ptop-pic img.leaving { opacity: 0; transition: opacity calc(420ms * var(--motion-scale)) var(--ease-out); }
.ptop-pic, .ptop-band { display: none; }
.ptop-crumb { justify-self: start; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: 0 0 6px -10px; padding: 0 10px; border-radius: var(--r-ctl);
  color: var(--muted); font-size: var(--t-13); font-weight: 550; text-decoration: none; }
.ptop-crumb .i { width: 16px; height: 16px; }
@media (hover: hover) { .ptop-crumb:hover { color: var(--ink); background: var(--page-deep); } }
.ptop-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
/* The previous and next arrows, beside the title: bordered squares, as in the concept, with the plan's place between
   them (1 / 2); the one with nowhere to go keeps its border, its chevron faint */
.ptop-steps { flex: none; display: inline-flex; align-items: center; gap: 2px; margin-left: 6px; translate: 0 3px; }
.ptop-count { min-width: 48px; padding: 0 4px; text-align: center; font-size: var(--t-15); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.btn.ptop-step { border-radius: var(--r-ctl); background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2); color: var(--ink); }
.ptop-step .i { width: 20px; height: 20px; }
.btn.ptop-step[disabled] { opacity: 1; color: var(--hair-2); }
/* The title: 76 px at 1440 (operator, 2026-10-30), scaling with its column; room under the line for the descenders (the
   "y" of family), taken back so the layout does not move. */
.ptop-name { min-width: 0; font-family: var(--font-display); font-optical-sizing: auto; font-weight: 600; font-size: clamp(30px, 10.9cqi, 76px); line-height: 1.06; letter-spacing: -0.022em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-bottom: 0.22em; margin-bottom: -0.22em; }
/* On the plan pages the chevron (44 px) and the arrows (140 px) share the row, so the title scales with what is left of its column */
@media (min-width: 600px) { :is(.pn-grid, .pr-grid) .ptop-name { font-size: clamp(24px, calc(16.4cqi - 38.8px), 76px); } }
.ptop-sub { margin-top: 2px; font-size: var(--t-15); font-weight: 500; color: var(--ink-2); }
/* The money beside the title: the key amount's mint glow, its centre on the amount's top-right corner, on the page, not
   out over the photo */
@media (min-width: 600px) {
  :is(ts-price-card, ts-spend-card)[data-layout="hero"] .stat.key .v::before { width: 150px; height: 150px; right: -77px; top: -53px; translate: none;
    background: radial-gradient(closest-side, color-mix(in oklch, var(--mint) 85%, transparent), color-mix(in oklch, var(--mint) 55%, transparent) 45%, transparent); }
}

/* 900-1279 px: the title, a thin divider and the money stay in one row; the photo narrows to the column right of the money
   (the screen's grid sets that column: 20vw on the planner, 18vw on progress, plus the gutter) and the key amount drops to 56 px;
   the title stops at 52 px, so it does not outgrow the four-column layout that follows */
@media (min-width: 900px) and (max-width: 1279px) {
  :is(.pn-grid, .pr-grid) .ptop-name { font-size: clamp(24px, calc(16.4cqi - 38.8px), 52px); }
  .ptop-div { height: 110px; }
  .ptop-photo, .ptop-over { width: calc(20vw + var(--gutter)); }
  body:has(.pr-grid) :is(.ptop-photo, .ptop-over) { width: calc(18vw + var(--gutter)); }
  :is(ts-price-card, ts-spend-card)[data-layout="hero"] .stat.key .v { font-size: var(--t-56); }
}
/* 600-899 px: the title and the money stacked on the left, the photo taller on the right */
@media (max-width: 899px) {
  .ptop-div { display: none; }
  .ptop-photo, .ptop-over { width: 38vw; height: 392px; }
  .ptop-name { font-size: clamp(30px, 8.4cqi, 76px); }
}

/* Under 600 px (6.0): the photo is a band above the title, full bleed, melting into the page at its bottom; the back
   link and the arrows sit on it */
@media (max-width: 599px) {
  .ptop-photo, .ptop-over { display: none; }
  .ptop-title { height: auto; align-content: start; padding-bottom: 4px; }
  .ptop-pic { display: block; position: relative; grid-row: 1; grid-column: 1; height: 168px; margin: -12px calc(-1 * var(--gutter)) 0; overflow: hidden;
    --fade: linear-gradient(to bottom, #000 0%, #000 30%, rgb(0 0 0 / 0.94) 42%, rgb(0 0 0 / 0.81) 52%, rgb(0 0 0 / 0.63) 62%, rgb(0 0 0 / 0.43) 72%, rgb(0 0 0 / 0.24) 82%, rgb(0 0 0 / 0.1) 90%, rgb(0 0 0 / 0.03) 96%, transparent 100%);
    -webkit-mask-image: var(--fade); mask-image: var(--fade); }
  /* what is drawn across the band (the light trail): the band's box, unmasked */
  .ptop-band { display: block; position: absolute; top: -12px; left: calc(-1 * var(--gutter)); right: calc(-1 * var(--gutter)); height: 168px; pointer-events: none; }
  .ptop-crumb { grid-row: 1; grid-column: 1; align-self: start; z-index: 1; margin: 0 0 0 -4px; background: oklch(100% 0 0 / 0.8); padding: 0 12px 0 8px; border-radius: var(--r-pill); color: var(--ink-2); }
  .ptop-row { margin-top: -44px; }
  /* the arrows and the plan's place: one pill on the band */
  .ptop-steps { position: absolute; top: 0; right: 0; margin: 0; translate: none; gap: 0; padding: 0 2px; border-radius: var(--r-pill); background: oklch(100% 0 0 / 0.8); }
  .btn.ptop-step { background: none; box-shadow: none; border-radius: var(--r-pill); color: var(--ink-2); }
  .btn.ptop-step[disabled] { color: var(--hair-2); }
  .ptop-count { min-width: 40px; padding: 0; font-size: var(--t-13); }
  .ptop-name { font-size: 30px; white-space: normal; overflow: visible; }
}
/* A short phone (760 px tall or less): the band is 56 px shorter (and the plan group takes less room above its first clip), so the first clip shows above the fixed bar on load */
@media (max-width: 599px) and (max-height: 760px) {
  .ptop-pic { height: 112px; }
  .ptop-band { top: -12px; height: 112px; }
}

/* ui/c/state.css */
/* Empty, error and loading states (.state-empty, .state-error, ts-skeleton). An empty state offers one action; an
   error says what happened and what to do; loading is skeleton shapes of the real layout, never a spinner page. */
.state-empty, .state-error { display: grid; justify-items: start; gap: 14px; padding: 28px 24px; border-radius: var(--r-card); }
.state-empty { background: var(--surface); box-shadow: var(--shadow-sm); }
.state-empty p { font-size: var(--t-17); color: var(--ink-2); max-width: 52ch; }
.state-error { grid-template-columns: auto minmax(0, 1fr); align-items: start; background: var(--bad-soft); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--bad) 22%, transparent); }
.state-error .i { width: 22px; height: 22px; color: var(--bad); margin-top: 1px; }
.state-error p { color: var(--ink); font-weight: 500; max-width: 60ch; }
.state-error .actions { grid-column: 2; }

ts-skeleton { display: block; }
.sk { border-radius: 10px; background: var(--page-deep); }
.sk-line { height: 12px; border-radius: 6px; background: var(--page-deep); }
.sk-cards { display: flex; gap: 14px; overflow: hidden; }
.sk-card { flex: 0 0 200px; display: grid; gap: 10px; padding: 12px; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); }
.sk-card .sk { aspect-ratio: 16 / 9; }
.sk-rows { display: grid; gap: 10px; }
.sk-row { display: grid; grid-template-columns: 64px minmax(0, 1fr) 72px; gap: 14px; align-items: center; padding: 12px; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); }
.sk-row .sk { aspect-ratio: 16 / 10; }
.sk-row .sk-stack { display: grid; gap: 8px; }
.sk-page { display: grid; gap: 16px; }
.sk-title { height: 34px; width: min(420px, 70%); border-radius: 10px; background: var(--page-deep); }

/* ui/c/tip.css */
/* Info tip and the shared popover panel (.pop). The (i) draws at 18 px inside a 44 px target that takes no room. */
ts-tip { display: inline-flex; vertical-align: middle; }
.tip-b { display: grid; place-items: center; width: 44px; height: 44px; margin: -13px -12px; border-radius: 50%; color: var(--faint);
  transition: color var(--d-tap) var(--ease-out); }
.tip-b .i { width: 17px; height: 17px; }
@media (hover: hover) { .tip-b:hover { color: var(--violet-ink); } }
.tip-b[aria-expanded="true"] { color: var(--violet); }

.pop { position: fixed; inset: auto; margin: 0; padding: 14px 16px; max-width: min(320px, calc(100vw - 24px)); border: 0; border-radius: var(--r-card);
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lift); font-size: var(--t-13); line-height: 1.5;
  opacity: 1; translate: 0 0;
  transition: opacity var(--d-fade) var(--ease-out), translate var(--d-quick) var(--ease-out), display var(--d-quick) allow-discrete, overlay var(--d-quick) allow-discrete; }
.pop:not(:popover-open) { display: none; opacity: 0; translate: 0 -4px; }
@starting-style { .pop:popover-open { opacity: 0; translate: 0 -4px; } }
.tip-pop p { color: var(--ink-2); font-size: var(--t-13); }
/* Under 600 px a popover is a bottom sheet */
.pop[data-sheet] { left: 0; right: 0; bottom: 0; top: auto; max-width: none; width: 100%; padding: 20px 20px calc(20px + env(safe-area-inset-bottom)); border-radius: var(--r-page) var(--r-page) 0 0; font-size: var(--t-15); }
.pop[data-sheet]:not(:popover-open) { translate: 0 24px; }
@starting-style { .pop[data-sheet]:popover-open { translate: 0 24px; } }
.pop[data-sheet] p { font-size: var(--t-15); }
.pop::backdrop { background: transparent; }
.pop[data-sheet]::backdrop { background: oklch(22% 0.02 285 / 0.22); }

/* ui/c/menu.css */
/* Menu: the trigger, and the list in the shared popover panel */
ts-menu { display: inline-flex; }
/* The avatar that opens the account menu */
.avatar { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--violet-soft); color: var(--violet-ink); font-weight: 650; font-size: var(--t-15); box-shadow: var(--shadow-sm); }
.avatar[aria-expanded="true"] { box-shadow: 0 0 0 1.5px var(--violet), var(--shadow-sm); }
.mn-select { justify-content: space-between; min-width: 200px; padding: 0 12px 0 16px; font-weight: 500; }
.mn-select .mn-chev { width: 16px; height: 16px; color: var(--muted); transition: rotate var(--d-quick) var(--ease-out); }
.mn-select[aria-expanded="true"] .mn-chev { rotate: 180deg; }
.mn-trig[aria-expanded="true"] { background: var(--violet-soft); color: var(--violet-ink); }
.mn-pop { gap: 2px; min-width: max(var(--anchor-w, 0px), 140px); width: max-content; padding: 6px; }
.mn-pop:popover-open { display: grid; }
.mn-pop[data-sheet] { padding: 10px 10px calc(14px + env(safe-area-inset-bottom)); gap: 4px; }
.mn-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: 8px 12px; border-radius: var(--r-ctl); text-align: left;
  font-size: var(--t-15); font-weight: 500; color: var(--ink); transition: background-color var(--d-tap); }
.mn-item:focus { outline: none; background: var(--violet-soft); }
.mn-item:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
@media (hover: hover) { .mn-item:not([aria-disabled="true"]):hover { background: var(--wash); } }
.mn-item.danger { color: var(--bad); }
.mn-item[aria-disabled="true"] { cursor: not-allowed; }
.mn-item[aria-disabled="true"] .mn-label { color: var(--faint); }
.mn-main { display: grid; gap: 1px; }
.mn-why { font-size: var(--t-13); font-weight: 400; color: var(--muted); }
.mn-on { width: 16px; height: 16px; color: var(--violet); }
.mn-item.on .mn-label { font-weight: 600; }
/* Cell (variant "cell"): a select with no frame; plan-strip.css sets its look. The face and the list carry a colour dot or an aspect-ratio box */
.mn-item > .mn-main { flex: 1; min-width: 0; }
.mn-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--c); }
.mn-ar { display: block; flex: none; box-sizing: border-box; border: 1.5px solid currentColor; border-radius: 2px; }
.mn-item > .mn-ar { margin: 0 6px 0 2px; color: var(--ink-2); }
.mn-item.on > .mn-ar { color: var(--violet-ink); }
.mn-item > .mn-dot { margin-right: -2px; }

/* ui/c/toast.css */
/* Toast: a pill fixed at the bottom centre, above the screen's fixed bar */
ts-toast { position: fixed; z-index: 80; left: 0; right: 0; bottom: calc(var(--toast-bottom, 24px) + env(safe-area-inset-bottom)); display: flex; justify-content: center;
  padding: 0 var(--gutter); pointer-events: none; }
ts-toast.leaving { pointer-events: none; }
.toast { pointer-events: auto; display: inline-flex; align-items: center; gap: 4px 14px; flex-wrap: wrap; max-width: 560px; min-height: 52px; padding: 8px 8px 8px 18px;
  border-radius: 18px; background: var(--ink); color: oklch(97% 0.005 286); box-shadow: 0 18px 40px -16px oklch(20% 0.03 285 / 0.5); font-size: var(--t-15); font-weight: 500; }
.toast:not(.has-act) { padding-right: 18px; }
.toast-t { padding: 4px 0; }
.toast-act { min-height: 44px; padding: 0 14px; border-radius: 12px; font-weight: 650; color: var(--mint); }
@media (hover: hover) { .toast-act:hover { background: oklch(100% 0 0 / 0.08); } }
.toast-act:focus-visible { outline-color: var(--mint); }

/* ui/c/note.css */
/* Save note: the toast's dark surface, small, hung under the control it concerns with a caret pointing up at it */
ts-note { display: inline-block; max-width: min(340px, calc(100vw - 2 * var(--gutter))); }
/* a note that appears is scrolled into view, clear of the floating Create */
ts-note { scroll-margin-bottom: 104px; }
.note-at { position: relative; }
.note-at > ts-note { position: absolute; z-index: 40; top: calc(100% + 10px); left: 0; width: max-content; margin-left: var(--nudge, 0px); }
.note-at > ts-note[data-align="center"] { left: 50%; translate: -50% 0; }
.note-at > ts-note[data-align="end"] { left: auto; right: 0; }
.note { position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: 2px 10px; min-height: 40px; padding: 8px 14px; border-radius: 12px;
  background: var(--ink); color: oklch(97% 0.005 286); box-shadow: 0 14px 32px -14px oklch(20% 0.03 285 / 0.55); font-size: var(--t-13); font-weight: 550; line-height: 1.35; text-align: left; }
.note.has-act { padding: 4px 4px 4px 14px; }
.note::before { content: ""; position: absolute; top: -5px; left: calc(18px - var(--nudge, 0px)); width: 10px; height: 10px; rotate: 45deg; border-radius: 2px 0 0 0; background: var(--ink); }
ts-note[data-align="center"] .note::before { left: calc(50% - 5px - var(--nudge, 0px)); }
ts-note[data-align="end"] .note::before { left: auto; right: calc(18px + var(--nudge, 0px)); }
ts-note:not(.note-at > *) .note::before { display: none; }
.note-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: oklch(70% 0.16 25); box-shadow: 0 0 0 3px oklch(70% 0.16 25 / 0.25); }
.note-t { min-width: 0; }
.note-act { min-height: 44px; min-width: 44px; padding: 0 12px; border-radius: 9px; font-weight: 650; color: var(--mint); }
@media (hover: hover) { .note-act:hover { background: oklch(100% 0 0 / 0.08); } }
.note-act:focus-visible { outline-color: var(--mint); }

/* ui/c/plans.css */
/* All plans: the chevron beside the planner's title and the panel with every plan, grouped by project */
ts-plans { display: inline-flex; }
.pl-trig { color: var(--ink-2); }
.pl-chev { width: 20px; height: 20px; transition: rotate var(--d-quick) var(--ease-out); }
.pl-trig[aria-expanded="true"] { background: var(--violet-soft); color: var(--violet-ink); }
.pl-trig[aria-expanded="true"] .pl-chev { rotate: 180deg; }
.pl-pop { width: min(420px, calc(100vw - 24px)); max-width: none; max-height: min(640px, calc(100vh - 120px)); overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 14px; }
.pl-pop:popover-open { display: grid; gap: 10px; }
.pl-pop[data-sheet] { width: 100%; max-height: 86vh; padding: 18px 16px calc(16px + env(safe-area-inset-bottom)); }
.pl-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pl-head .t-title { font-size: var(--t-17); }
.pl-count, .pl-cap { font-size: var(--t-13); color: var(--muted); }
.pl-cap { margin-top: -6px; }
.pl-groups { display: grid; gap: 14px; }
.pl-group { display: grid; gap: 4px; }
.pl-proj { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 0 2px 2px; border-bottom: 1px solid var(--hair); }
.pl-pname { font-size: var(--t-13); font-weight: 650; color: var(--ink-2); }
.pl-sub { font-size: var(--t-13); color: var(--muted); font-variant-numeric: tabular-nums; }
.pl-sub b { font-weight: 600; color: var(--ink-2); }
.pl-sub { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 0 12px; }
.pl-list { display: grid; gap: 2px; }
.pl-row { display: flex; align-items: center; gap: 2px; border-radius: var(--r-ctl); transition: background-color var(--d-quick) var(--ease-out); }
.pl-row.cur { background: var(--violet-soft); }
.pl-tick { flex: none; margin: 0; }
.pl-go { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; padding: 6px 10px 6px 2px; border-radius: var(--r-ctl); text-align: left; }
@media (hover: hover) { .pl-row:not(.cur) .pl-go:hover { background: var(--wash); } }
.pl-go:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
.pl-id { display: grid; gap: 1px; min-width: 0; }
.pl-name { font-size: var(--t-15); font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-meta { font-size: var(--t-13); color: var(--muted); }
.pl-cost { flex: none; display: grid; justify-items: end; gap: 1px; }
.pl-amt { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-15); font-variant-numeric: tabular-nums lining-nums; }
.pl-kept { font-size: 12px; color: var(--muted); }
.pl-row.off .pl-name, .pl-row.off .pl-amt { color: var(--ink-2); }
.pl-row.off .pl-amt { opacity: 0.6; }
.pl-new { justify-self: start; margin-left: 4px; color: var(--violet-ink); }
.pl-new .i { width: 16px; height: 16px; }
.pl-kind { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 4px 2px; }
.pl-np { padding: 4px 2px 0; }
.pl-np .fh.bad { color: var(--bad); }
.pl-acts { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 12px; border-top: 1px solid var(--hair); }
.pl-acts .btn .i { width: 16px; height: 16px; }
.pl-why { font-size: var(--t-13); color: var(--muted); }

/* ui/c/history.css */
/* History: one row per saved version, who and when, with its Restore this version */
ts-history { display: block; }
.hi-list { display: grid; }
.hi-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; min-height: 60px; padding: 8px 0; border-bottom: 1px solid var(--hair); }
.hi-row:last-child { border-bottom: 0; }
.hi-t { font-size: var(--t-15); color: var(--ink); font-variant-numeric: tabular-nums; }
.hi-row.cur .hi-t { font-weight: 600; }

/* ui/c/picture.css */
/* Picture: the image as large as the window allows, its name and Close under it; it opens as the dialog does */
ts-picture { display: contents; }
.pic-dlg { width: min(1040px, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px); padding: 12px; border: 0; border-radius: var(--r-page); background: var(--surface); color: var(--ink);
  box-shadow: 0 30px 80px -20px oklch(25% 0.04 285 / 0.4);
  transition: opacity var(--d-fade) var(--ease-out), scale var(--d-move) var(--ease-spring), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.pic-dlg:not([open]) { opacity: 0; scale: 0.96; }
@starting-style { .pic-dlg[open] { opacity: 0; scale: 0.96; } }
.pic-dlg::backdrop { background: oklch(22% 0.02 285 / 0.55); transition: opacity var(--d-fade), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.pic-dlg:not([open])::backdrop { opacity: 0; }
@starting-style { .pic-dlg[open]::backdrop { opacity: 0; } }
.pic-dlg img { display: block; width: 100%; max-height: calc(100dvh - 120px); object-fit: contain; border-radius: var(--r-card); background: var(--wash); }
.pic-f { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 2px 0; }
.pic-n { min-width: 0; font-size: var(--t-13); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ui/c/start-from.css */
/* Starts from: the mode switch, then the frames or the references it uses; the shot editor's open prompt and the editor box */
ts-start-from { display: grid; gap: 12px; min-width: 0; container: sf / inline-size; }
.sf-gl { font-size: var(--t-13); font-weight: 600; color: var(--muted); }
.sf-note { font-size: var(--t-13); color: var(--violet-ink); }
.sf-mode-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
/* What a prompt starts from: three choices with a thumb that slides to the chosen one (--i is its place) */
.sf-seg { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: min(100%, 420px); padding: 4px; border-radius: 14px; background: var(--page-deep);
  box-shadow: inset 0 1px 2px oklch(25% 0.02 285 / 0.08); }
.sf-thumb { position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc((100% - 8px) / 3); border-radius: 10px; background: var(--surface); box-shadow: var(--shadow-sm), 0 0 0 1.5px var(--violet);
  translate: calc(var(--i, 0) * 100%) 0; }
.sf-seg button { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 7px; min-height: 44px; min-width: 0; border-radius: 10px;
  font-size: var(--t-13); font-weight: 500; color: var(--muted); white-space: nowrap; }
.sf-seg button .i { flex: none; width: 18px; height: 18px; }
.sf-seg button[aria-checked="true"] { color: var(--violet-ink); font-weight: 600; }
.sf-seg button[disabled] { cursor: default; }
/* Frames, off for a model that takes no frame (no_frames) */
.sf-seg button.na { opacity: 0.4; }
.sf-why { font-size: 12.5px; color: var(--muted); }
/* each choice answers a press anywhere in its third of the pill, the pill's 4 px edge included */
.sf-seg button::after { content: ""; position: absolute; inset: -4px 0; }
.sf-seg button:first-of-type::after { left: -4px; }
.sf-seg button:last-of-type::after { right: -4px; }
.sf-seg.locked .sf-thumb { opacity: 0.45; }
.sf-seg.locked button:not([aria-checked="true"]) { opacity: 0.45; }
.sf-seg button:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .sf-thumb { transition: translate var(--d-move) var(--ease-out); }
  html:not([data-motion="reduce"]) .sf-seg button { transition: color var(--d-quick); }
}
/* Frames: the first and last frame side by side, the clip's lengths running between them */
.sf-pair { display: grid; grid-template-columns: minmax(0, 1fr) 64px minmax(0, 1fr); row-gap: 8px; align-items: start; }
.sf-slot { display: contents; }
.sf-slot-h { grid-row: 1; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 8px; min-height: 44px; min-width: 0; }
.sf-slot-n { font-size: var(--t-13); font-weight: 600; white-space: nowrap; }
.sf-slot-h .mn-select { min-width: 0; max-width: 100%; padding: 0 10px 0 12px; font-size: var(--t-13); border-radius: 999px; }
.sf-fixed { font-size: var(--t-13); font-weight: 500; color: var(--violet-ink); }
.sf-slot-th { grid-row: 2; min-width: 0; }
.sf-slot-th .sf-th { width: 100%; border-radius: 10px; }
.sf-slot-th .sf-th img { border-radius: 10px; }
.sf-slot-th .sf-th.none { padding: 12px; text-align: center; font-size: var(--t-13); color: var(--muted); }
.sf-slot-f { grid-row: 3; display: flex; align-items: center; gap: 4px; min-height: 28px; min-width: 0; font-size: 12.5px; color: var(--muted); }
.sf-fn { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-slot-f .btn { margin-left: auto; }
.s-first > * { grid-column: 1; }
.s-last > * { grid-column: 3; }
.sf-run { grid-column: 2; grid-row: 2; align-self: center; position: relative; height: 0; }
.sf-run::before { content: ""; position: absolute; left: 10px; right: 12px; top: 0; height: 1.5px; background: var(--hair-2); }
.sf-run::after { content: ""; position: absolute; right: 10px; top: -4px; width: 8px; height: 8px; border: solid var(--hair-2); border-width: 1.5px 1.5px 0 0; rotate: 45deg; }
.sf-run span { position: absolute; left: 50%; top: 0; translate: -50% -50%; padding: 1px 7px; border-radius: 999px; background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: 11.5px; font-weight: 600; color: var(--ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; z-index: 1; }
/* References: a switch on each of the shot's references */
.sf-refs { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 160px)); gap: 12px; }
.sf-rtog { position: relative; display: block; width: 100%; min-height: 44px; border-radius: 8px; }
.sf-rtog:focus-visible { outline: 2px solid var(--violet); outline-offset: 4px; }
.sf-chk { position: absolute; right: 6px; top: 6px; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: color-mix(in oklch, var(--surface) 92%, transparent);
  box-shadow: inset 0 0 0 1.5px var(--hair-2); color: transparent; }
.sf-chk .i { width: 14px; height: 14px; stroke-width: 2.4; }
.sf-rtog[aria-pressed="true"] .sf-chk { background: var(--violet); box-shadow: none; color: #fff; }
.sf-rt.off .sf-th.inherit { box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px var(--hair-2); }
.sf-rt.off .sf-th img { opacity: 0.4; filter: saturate(0); }
.sf-rcap { margin-top: 4px; font-size: 12px; color: var(--muted); }
.sf-rt.off .sf-rcap { color: var(--faint); }
.sf-th { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden; background: var(--page-deep); }
.sf-th img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
.sf-th.inherit { overflow: visible; box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px color-mix(in oklch, var(--violet) 32%, transparent); }
.sf-th.inherit img { border-radius: 6px; }
.sf-th.story img { filter: saturate(0.6); }
.sf-th.none { display: grid; place-items: center; align-content: center; gap: 8px; background: none; outline: 1.5px dashed var(--hair-2); outline-offset: -1.5px; color: var(--faint); }
.sf-th.none .i { width: 18px; height: 18px; }
.sf-th.cont { display: grid; place-items: center; overflow: visible; color: var(--violet); background: linear-gradient(160deg, var(--wash), var(--violet-soft));
  box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px color-mix(in oklch, var(--violet) 32%, transparent); }
.sf-th.cont img { position: absolute; inset: 0; opacity: 0.45; filter: saturate(0); border-radius: 6px; }
.sf-th.cont .i { position: relative; width: 22px; height: 22px; }
.sf-mark { position: absolute; left: 8px; bottom: 8px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: color-mix(in oklch, var(--surface) 92%, transparent);
  color: var(--violet-ink); box-shadow: 0 1px 3px oklch(25% 0.03 285 / 0.25); }
.sf-mark .i { width: 14px; height: 14px; }
.sf-sbtag { position: absolute; left: 5px; bottom: 5px; display: inline-flex; align-items: center; height: 18px; padding: 0 7px; border-radius: 999px; font-size: 10.5px; font-weight: 600;
  background: color-mix(in oklch, var(--surface) 90%, transparent); color: var(--ink-2); }
@container sf (max-width: 460px) {
  .sf-pair { grid-template-columns: minmax(0, 1fr); }
  .sf-slot > * { grid-column: 1; }
  .s-first .sf-slot-h { grid-row: 1; } .s-first .sf-slot-th { grid-row: 2; } .s-first .sf-slot-f { grid-row: 3; }
  .s-last .sf-slot-h { grid-row: 5; } .s-last .sf-slot-th { grid-row: 6; } .s-last .sf-slot-f { grid-row: 7; }
  .sf-run { grid-column: 1; grid-row: 4; height: 40px; }
  .sf-run::before { left: 50%; right: auto; top: 4px; bottom: 6px; width: 1.5px; height: auto; }
  .sf-run::after { left: 50%; right: auto; top: auto; bottom: 6px; translate: -3.5px 0; rotate: 135deg; }
  .sf-run span { top: 50%; }
  .sf-slot-f:empty { display: none; }
}
@container sf (max-width: 380px) { .sf-seg button .i { display: none; } }

/* Add references (the editor box): a dashed tile at a reference's size */
.sf-add { display: grid; place-items: center; align-content: center; gap: 4px; width: 100%; aspect-ratio: 16 / 9; min-height: 44px; border-radius: 6px; outline: 1.5px dashed color-mix(in oklch, var(--violet) 40%, var(--hair-2)); outline-offset: -1.5px;
  font-size: 12px; font-weight: 600; color: var(--violet-ink); }
.sf-add .i { width: 18px; height: 18px; }
@media (hover: hover) { .sf-add:hover { background: var(--violet-soft); } }
.sf-add:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
/* In the editor box the frames keep a modest size beside the box's other fields */
ts-start-from[data-place="box"] .sf-pair { max-width: 560px; }
ts-start-from[data-place="box"] .sf-refs { grid-template-columns: repeat(auto-fill, minmax(112px, 140px)); }
ts-start-from.locked .sf-seg button:not([aria-checked="true"]) { color: var(--faint); }
/* The frame-shape badge (TS.misBadge): a warm pill over the picture's top-left corner; a tile too small for its words shows the "!" */
.sf-slot-th { position: relative; }
.mis-b { position: absolute; top: 8px; left: 8px; z-index: 1; display: inline-flex; align-items: center; gap: 6px; max-width: calc(100% - 16px); height: 24px; padding: 0 9px 0 4px; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn-ink); box-shadow: 0 0 0 1px color-mix(in oklch, var(--warn-ink) 28%, transparent), 0 2px 6px -2px oklch(30% 0.05 60 / 0.35);
  font-size: 12px; font-weight: 600; white-space: nowrap; }
.mis-b > i { display: grid; place-items: center; flex: none; width: 16px; height: 16px; border-radius: 50%; background: var(--warn-ink); color: #fff; font-size: 11px; font-weight: 800; font-style: normal; line-height: 1; }
.mis-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.se-tile .mis-b { top: 5px; left: 5px; padding: 0 4px; }
.se-tile .mis-b .mis-t { display: none; }
.se-tile:has(.mis-b) .se-tsub { color: var(--warn-ink); font-weight: 600; }
/* A shared description's reference the shot uses: dimmed, not a switch (the description holds it) */
.sf-rt.inh .sf-th { display: block; }

/* ui/c/desc-editor.css */
/* Shared descriptions editor: the shot editor's head, tiles and quiet buttons (shot-editor.css); a card per description
   with its tick, its Look and Characters fields beside its references */
ts-desc-editor { display: grid; gap: 12px; min-width: 0; scroll-margin-bottom: 104px; container: de / inline-size; }
ts-desc-editor[data-layout="dock"] { padding: 14px 18px 18px; border-radius: var(--r-card); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair); }
.de-help { margin-top: -6px; }
.de-list { display: grid; gap: 10px; }
.de-card { display: grid; gap: 10px; padding: 4px 14px 14px; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); scroll-margin-bottom: 104px; }
.de-card.open { box-shadow: 0 0 0 2px var(--violet), var(--shadow-sm); }
.de-h { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; min-height: 44px; }
.de-n { font-size: var(--t-15); font-weight: 650; color: var(--ink); }
.de-card.off .de-n, .de-card.off .de-fields { opacity: 0.55; }
.de-acts { display: inline-flex; gap: 2px; margin-left: auto; margin-right: -8px; }
.de-b { display: grid; gap: 14px; }
.de-fields { display: grid; gap: 12px; }
.de-field { display: grid; gap: 6px; }
.de-fh { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.de-ta { width: 100%; padding: 10px 12px; border: 0; border-radius: var(--r-ctl); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-15); line-height: 1.5; color: var(--ink); resize: vertical; field-sizing: content; min-height: calc(2lh + 20px); }
.de-ta:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet); }
ts-desc-editor.locked .de-ta { color: var(--ink-2); }
.de-refs { display: grid; gap: 8px; align-content: start; }
.de-refs .se-trow { padding-top: 4px; }
.de-add { justify-self: start; margin-left: -4px; }
@container de (min-width: 760px) {
  .de-b { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); column-gap: 24px; }
}

/* ui/c/refine-box.css */
/* Refine box: a just-added shot or take under the plan's shots, ringed in the violet of its dashed card */
/* A white box with a hairline, as in the concept; scrolled into view it clears the floating Create */
ts-refine-box { position: relative; display: grid; gap: 14px; min-width: 0; margin-top: 4px; padding: 16px 18px 18px; border-radius: var(--r-card); background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hair), var(--shadow-sm); scroll-margin-bottom: 104px; container: rb / inline-size; }
.rb-tl { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.rb-id { display: inline-grid; place-items: center; min-width: 24px; height: 24px; padding: 0 7px; border-radius: 7px; background: var(--violet-soft); color: var(--violet-ink); font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums lining-nums; }
.rb-tag { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; background: var(--violet-soft); color: var(--violet-ink);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 30%, transparent); }
.rb-cols { display: grid; gap: 16px; }
.rb-col { display: grid; gap: 14px; align-content: start; min-width: 0; }
.rb-f { display: grid; gap: 6px; min-width: 0; }
.rb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.rb-l { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); }
.rb-title, .rb-text { width: 100%; border: 0; border-radius: var(--r-ctl); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2); font-size: var(--t-15); color: var(--ink); }
.rb-title { height: 44px; padding: 0 12px; }
.rb-text { padding: 10px 12px; line-height: 1.5; resize: vertical; field-sizing: content; min-height: 4lh; }
.rb-title:focus, .rb-text:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 4px var(--violet-soft); }
ts-refine-box.locked .rb-title, ts-refine-box.locked .rb-text { color: var(--ink-2); }
/* The length and the join: a row of pills, the chosen one filled */
.rb-seg { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.rb-seg button { min-width: 44px; min-height: 44px; padding: 0 18px; border-radius: 999px; background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-13); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums;
  transition: background-color var(--d-quick) var(--ease-out), box-shadow var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.rb-seg button[aria-checked="true"] { background: var(--violet-soft); color: var(--violet-ink); box-shadow: inset 0 0 0 1.5px var(--violet); }
@media (hover: hover) { .rb-seg button[aria-checked="false"]:hover { color: var(--violet-ink); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 45%, transparent); } }
.rb-seg button:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.rb-kept { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; background: var(--mint-soft); color: var(--mint-ink); }
.rb-seg button[disabled] { cursor: default; opacity: 0.6; }
.rb-ft-l { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.rb-ft { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding-top: 12px; border-top: 1px solid color-mix(in oklch, var(--violet) 18%, var(--hair)); }
.rb-another .i { width: 15px; height: 15px; }
.rb-done { min-width: 120px; }
@container rb (max-width: 480px) { .rb-ft > .btn, .rb-ft-l, .rb-ft-l .btn { flex: 1 1 100%; } }
/* from a 720 px box the shot title's label sits to the left of its field */
@container rb (min-width: 720px) { .rb-tf { grid-template-columns: auto minmax(0, 470px); justify-content: start; align-items: center; gap: 12px; } }
@container rb (min-width: 720px) { .rb-cols { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); column-gap: 28px; } }
/* In the phone's bottom sheet the sheet is the box; its buttons stay at the sheet's foot */
ts-sheet ts-refine-box { margin: 0; padding: 0; background: none; box-shadow: none; }
ts-sheet .rb-ft { position: sticky; bottom: 0; z-index: 1; margin: 0 -4px; padding: 12px 4px max(12px, env(safe-area-inset-bottom)); background: var(--surface); }
/* The join: one segmented control, a white pill track with the chosen part lavender, Cut or Continuous */
.rb-seg.rb-join { gap: 0; padding: 4px; border-radius: 999px; background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair); }
.rb-join button { min-height: 44px; border-radius: 999px; background: none; box-shadow: none; }
.rb-join button[aria-checked="true"] { background: var(--violet-soft); color: var(--violet-ink); box-shadow: none; }
@media (hover: hover) { .rb-join button[aria-checked="false"]:hover { box-shadow: none; } }
.rb-shared { font-size: 12.5px; color: var(--muted); }
/* The lengths: a chip per length, ticked where this prompt has a take at it; the open take's own length is solid violet.
   A small field after them takes any other length in the model's range */
.rb-lens { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rb-len { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px 0 10px; border-radius: 999px; background: var(--surface); color: var(--ink-2);
  box-shadow: inset 0 0 0 1px var(--hair-2); font-size: var(--t-15); font-weight: 600; font-variant-numeric: tabular-nums lining-nums;
  transition: background-color var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out), box-shadow var(--d-quick) var(--ease-out); }
.rb-len-t { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 6px; box-shadow: inset 0 0 0 1.5px var(--hair-2); background: var(--surface); }
.rb-len-t .i { width: 12px; height: 12px; stroke-width: 2.6; opacity: 0; scale: 0.6; transition: opacity var(--d-tap), scale var(--d-quick) var(--ease-spring); }
.rb-len[aria-checked="true"] { background: var(--violet-soft); color: var(--violet-ink); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 35%, transparent); }
.rb-len[aria-checked="true"] .rb-len-t { background: var(--violet); box-shadow: none; color: #fff; }
.rb-len[aria-checked="true"] .rb-len-t .i { opacity: 1; scale: 1; }
.rb-len.own[aria-checked="true"] { background: var(--violet); color: #fff; box-shadow: none; }
.rb-len.own .rb-len-t { background: #fff; color: var(--violet); }
@media (hover: hover) { .rb-len:not([disabled]):not(.own):hover { box-shadow: inset 0 0 0 1.5px var(--violet); } }
.rb-len[disabled] { cursor: default; opacity: 0.7; }
.rb-len:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.rb-lenf { display: inline-flex; align-items: center; gap: 2px; min-height: 44px; padding: 0 12px 0 10px; border-radius: 999px; color: var(--violet-ink);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 35%, var(--hair-2)); }
.rb-lenf:focus-within { box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 3px var(--violet-soft); }
.rb-len-p { width: 14px; height: 14px; stroke-width: 2.2; }
/* the field is a 44 px target; a short line under its digits says it takes a number */
.rb-len-in { width: 44px; height: 44px; margin: 0 -8px; padding: 0; border: 0; border-radius: 0; text-align: center; font-size: var(--t-15); font-weight: 650; color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums; background: linear-gradient(var(--hair-2), var(--hair-2)) center calc(50% + 11px) / 2.6ch 1.5px no-repeat; }
.rb-len-in:focus { outline: none; background-image: linear-gradient(var(--violet), var(--violet)); background-size: 2.6ch 2px; }
.rb-len-u { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); }
/* Why a choice is off (Continuous with a model that cannot continue): a line under the row */
.rb-why { flex: 1 1 100%; font-size: 12.5px; color: var(--muted); }
/* The ⋯ menu at the top right: shown while the pointer is over the box or the focus is in it (always on touch); its place
   stays, the label row and the right column keep clear of it */
.rb-menu { position: absolute; top: 8px; right: 8px; z-index: 1; }
.rb-tl { min-height: 32px; padding-right: 44px; }
@container rb (min-width: 720px) { .rb-tl { padding-right: 0; } .rb-cols > .rb-col + .rb-col { padding-right: 44px; } }
ts-sheet .rb-menu { top: -6px; right: -4px; }
@media (hover: hover) {
  .rb-menu { opacity: 0; visibility: hidden; }
  ts-refine-box:hover .rb-menu, ts-refine-box:focus-within .rb-menu, .rb-menu:has([aria-expanded="true"]) { opacity: 1; visibility: visible; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .rb-menu { transition: opacity 120ms var(--ease-out), visibility 120ms var(--ease-out); }
}

/* ui/c/dialog.css */
/* Dialog: centred, scales in from 0.96; the backdrop fades. Movement is instant under reduced motion, the fade stays. */
.dlg { width: min(480px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); padding: 0; border: 0; border-radius: var(--r-page); background: var(--surface); color: var(--ink);
  box-shadow: 0 30px 80px -20px oklch(25% 0.04 285 / 0.4), 0 0 0 1px oklch(25% 0.02 285 / 0.06);
  transition: opacity var(--d-fade) var(--ease-out), scale var(--d-move) var(--ease-spring), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.dlg:not([open]) { opacity: 0; scale: 0.96; }
@starting-style { .dlg[open] { opacity: 0; scale: 0.96; } }
.dlg::backdrop { background: oklch(22% 0.02 285 / 0.32); transition: opacity var(--d-fade), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.dlg:not([open])::backdrop { opacity: 0; }
@starting-style { .dlg[open]::backdrop { opacity: 0; } }
.dlg-in { display: grid; gap: 10px; padding: 24px 24px 20px; }
.dlg-x { color: var(--ink-2); font-size: var(--t-15); max-width: 52ch; }
.dlg-act { justify-content: flex-end; margin-top: 12px; }
@media (max-width: 599px) { .dlg-act { display: grid; grid-template-columns: 1fr 1fr; } .dlg-act .btn { width: 100%; min-width: 0; white-space: normal; text-wrap: balance; line-height: 1.25; } }

/* ui/c/sheet.css */
/* Sheet: a side sheet from 600 px, a bottom sheet under it. The surface rises (or slides in) with the spring. */
.sh { position: fixed; inset: 0 0 0 auto; width: min(460px, 100vw); height: 100dvh; max-height: none; max-width: none; margin: 0; padding: 0; border: 0;
  border-radius: var(--r-page) 0 0 var(--r-page); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lift); overflow: auto; overscroll-behavior: contain;
  translate: 0 0; opacity: 1;
  transition: translate var(--d-slow) var(--ease-spring), opacity var(--d-fade) var(--ease-out), display var(--d-slow) allow-discrete, overlay var(--d-slow) allow-discrete; }
.sh:not([open]) { translate: 100% 0; }
@starting-style { .sh[open] { translate: 100% 0; } }
.sh::backdrop { background: oklch(22% 0.02 285 / 0.28); transition: opacity var(--d-fade), display var(--d-slow) allow-discrete, overlay var(--d-slow) allow-discrete; }
.sh:not([open])::backdrop { opacity: 0; }
@starting-style { .sh[open]::backdrop { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .sh:not([open]) { opacity: 0; } @starting-style { .sh[open] { opacity: 0; } } }
html[data-motion="reduce"] .sh:not([open]) { opacity: 0; }
.sh.dragging { transition: none; }
/* A shared-element morph (TS.flow.step) moves the sheet itself, so its own rise stays off while one runs */
html.vt-on .sh, html.vt-on .sh::backdrop { transition: none; }
.sh-grip { display: none; }
.sh-head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 16px 8px 24px; background: var(--surface); }
.sh-body { padding: 4px 24px 28px; display: grid; gap: 16px; }
@media (max-width: 599px) {
  .sh { inset: auto 0 0 0; width: 100%; height: auto; max-height: 88dvh; border-radius: var(--r-page) var(--r-page) 0 0; padding-bottom: env(safe-area-inset-bottom); }
  .sh:not([open]) { translate: 0 100%; }
  @starting-style { .sh[open] { translate: 0 100%; } }
  .sh-grip { display: grid; place-items: center; position: sticky; top: 0; z-index: 3; height: 28px; background: var(--surface); touch-action: none; cursor: grab; }
  .sh-grip span { width: 40px; height: 5px; border-radius: 3px; background: var(--hair-2); }
  .sh-head { top: 28px; padding: 0 12px 6px 20px; }
  .sh-body { padding: 4px 20px 24px; }
}

/* ui/c/header.css */
/* App header. Desktop: one row; under 900 px the gaps and nav padding narrow, the balance drops its label and the agent pill is a dot. Under 600 px: the brand and the balance pill, then the tabs as a second row. */
ts-header { display: block; }
.hdr { position: relative; z-index: 30; background: color-mix(in oklch, var(--page) 88%, transparent); box-shadow: 0 1px 0 var(--hair); }
.hdr.clear { background: transparent; box-shadow: none; }
.hdr-in { display: flex; align-items: center; gap: 8px 28px; min-height: 64px; }
.brand { display: inline-flex; align-items: center; gap: 9px; min-height: 44px; color: var(--ink); text-decoration: none; font-weight: 650; font-size: var(--t-17); letter-spacing: -0.015em; }
.brand-mark { flex: none; width: 22px; height: 22px; color: var(--violet-mark); filter: drop-shadow(0 2px 6px color-mix(in oklch, var(--violet) 35%, transparent)); }
.brand .brand-gc { font-weight: 900; color: var(--violet); }
.hdr-nav { display: flex; align-items: center; gap: 4px; }
.nav-a { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: var(--r-ctl); color: var(--ink-2); font-weight: 550;
  text-decoration: none; transition: color var(--d-quick) var(--ease-out), background-color var(--d-quick) var(--ease-out); }
.nav-a::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 4px; height: 2px; border-radius: 2px; background: var(--violet); scale: 0 1;
  transition: scale var(--d-move) var(--ease-spring); }
.nav-a.on { color: var(--ink); }
.nav-a.on::after { scale: 1 1; }
@media (hover: hover) { .nav-a:not(.on):hover { color: var(--ink); background: var(--page-deep); } }
.hdr-r { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.bal { display: inline-flex; gap: 7px; min-height: 44px; align-items: center; padding: 0 14px; border-radius: 999px; background: var(--surface);
  box-shadow: var(--shadow-sm); color: var(--ink-2); text-decoration: none; font-size: var(--t-13); font-weight: 550; }
.bal-v { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-17); color: var(--ink); }
.bal.on { box-shadow: 0 0 0 1.5px var(--violet), var(--shadow-sm); }
.acct { flex: none; }
.hdr-tabs { display: none; }
@media (max-width: 899px) {
  .hdr-in { column-gap: 16px; }
  .hdr-r { gap: 8px; }
  .hdr-nav .nav-a { padding: 0 8px; }
  .hdr-nav .nav-a::after { left: 8px; right: 8px; }
  .bal-l { display: none; }
}
@media (max-width: 599px) {
  .hdr-in { min-height: 60px; gap: 8px; }
  .hdr-nav { display: none; }
  .hdr-r { gap: 8px; }
  .bal { padding: 0 14px; }
  .hdr-tabs { display: block; padding-bottom: 6px; }
  .hdr-tabnav { display: flex; gap: 2px; margin: 0 -8px; }
  .hdr-tabnav .nav-a { padding: 0 10px; }
  .hdr-tabnav .nav-a::after { left: 10px; right: 10px; bottom: 6px; }
}

/* ui/c/agent-bar.css */
/* Agent pill: the header's pill, a dot and the state in words; the popover holds the latest action, Activity, Pause */
ts-agent-bar { display: inline-flex; }
.ap { position: relative; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px 0 12px; border-radius: 999px;
  font-size: var(--t-13); font-weight: 600; color: var(--ink); white-space: nowrap; }
.ap > * { position: relative; }
.ap > .ap-bg { position: absolute; inset: 0; border-radius: 999px; background: var(--surface); box-shadow: var(--shadow-sm); transition: box-shadow var(--d-quick) var(--ease-out), background-color var(--d-quick) var(--ease-out); }
.ap[aria-expanded="true"] > .ap-bg { box-shadow: 0 0 0 1.5px var(--violet), var(--shadow-sm); }
@media (hover: hover) { .ap:hover > .ap-bg { box-shadow: 0 0 0 1px var(--hair-2), var(--shadow-sm); } }
.ap-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--mint-deep); box-shadow: 0 0 3px 0 color-mix(in oklch, var(--mint-deep) 25%, transparent); transition: background-color var(--d-move); }
.ap.paused .ap-dot { background: var(--warn); box-shadow: none; }
.ap.paused { color: var(--warn-ink); }
.ap.paused > .ap-bg { background: var(--warn-soft); }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .ap.working .ap-dot { animation: live-glow calc(3.6s * max(var(--motion-scale), 1)) ease-in-out infinite; }
}
.ap-pop { width: min(400px, calc(100vw - 24px)); padding: 16px 18px 14px; }
.ap-last { font-size: var(--t-13); color: var(--ink-2); margin-bottom: 10px; }
.ap-t { font-size: var(--t-17); margin-bottom: 2px; }
.ap-acts { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hair); }
.ap-follow { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); gap: 8px; }
.ap-pause { min-height: 44px; gap: 6px; margin-left: auto; }
.ap-pause .i { width: 15px; height: 15px; }
.ap-pause.on { color: var(--warn-ink); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--warn) 50%, transparent); }
@media (max-width: 899px) {
  .ap { width: 44px; padding: 0; justify-content: center; }
  .ap-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 599px) {
  .ap-pop { padding: 20px 20px calc(16px + env(safe-area-inset-bottom)); }
}

/* ui/c/activity.css */
/* Activity list */
ts-activity { display: block; }
.act { display: grid; }
.act-li { display: grid; grid-template-columns: 8px minmax(0, 1fr) auto; align-items: center; gap: 4px 12px; min-height: 48px; padding: 6px 0; font-size: var(--t-15); }
.act-li + .act-li { border-top: 1px solid var(--hair); }
.act-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); }
.act-dot.agent { background: var(--violet); }
.act-t { color: var(--ink-2); min-width: 0; }
.act-who { font-weight: 600; color: var(--ink); }
.act-who.agent { color: var(--violet-ink); }
.act-at { font-size: var(--t-13); color: var(--muted); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; justify-self: end; }
.act-r { display: inline-flex; align-items: center; gap: 10px; justify-self: end; }
.act-restore { min-height: 44px; }
.act-empty { color: var(--muted); padding: 12px 0; }

/* ui/c/public.css */
/* Public header and footer */
ts-public-header { display: block; }
.hdr.pub { background: transparent; box-shadow: none; }
.pub-nav { display: flex; gap: 2px; margin-left: auto; }
.pub-cta { min-height: 44px; }
@media (max-width: 599px) { .pub-nav .nav-a { padding: 0 8px; } .hdr.pub .hdr-in { gap: 4px; } }
.foot { margin-top: 56px; padding: 18px 0 calc(18px + env(safe-area-inset-bottom)); box-shadow: 0 -1px 0 var(--hair); }
.foot-in { display: flex; flex-wrap: wrap; gap: 0 20px; }
.foot a, .foot-b { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; font-size: var(--t-13); color: var(--muted); text-decoration: none; }
@media (hover: hover) { .foot a:hover, .foot-b:hover { color: var(--ink); text-decoration: underline; } }
/* The hero page's header (size "hero"): 100 high, the brand 30 px with a 40 px mark and no glow, across the full window width (the
   brand 28 in from the left edge, the links 28 in from the right) */
.hdr.pub.hero .hdr-in { min-height: 100px; max-width: none; padding-inline: 28px; }
.hdr.pub.hero .brand { gap: 10px; font-size: 30px; letter-spacing: -0.055em; }
.hdr.pub.hero .brand-mark { width: 40px; height: 40px; margin-block: -1px; filter: none; }
@media (max-width: 599px) { .hdr.pub.hero .hdr-in { min-height: 60px; max-width: var(--content); padding-inline: var(--gutter); } .hdr.pub.hero .brand { gap: 9px; font-size: var(--t-17); } .hdr.pub.hero .brand-mark { width: 22px; height: 22px; margin-block: 0; } }
/* Sign in while sign-up is by invitation (cta "signin", after waitlist-gpt-1): a borderless pill in the page's deep
   tone; the hero header's Pricing and API speak at the pill's size */
.hdr.pub .pub-in { isolation: isolate; border-radius: 999px; background: none; box-shadow: none; padding: 0 18px; font-weight: 500; color: var(--ink); }
/* the pill's fill is 32 high (the concept's chip is 31), drawn by ::before inside the 44 px target */
.hdr.pub .pub-in::before { content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: 50%; height: 32px; translate: 0 -50%; border-radius: inherit; background: var(--page-deep); transition: background-color var(--d-quick) var(--ease-out); }
@media (hover: hover) { .hdr.pub .pub-in:hover { background: none; box-shadow: none; } .hdr.pub .pub-in:hover::before { background: color-mix(in oklch, var(--page-deep) 80%, var(--ink) 6%); } }
.hdr.pub.hero .nav-a, .hdr.pub.hero .pub-in { font-size: var(--t-13); font-weight: 500; }
/* .foot.line: a quiet legal line, centred close under the page's last line, with no hairline */
.foot.line { margin-top: 0; padding: 0 0 calc(10px + env(safe-area-inset-bottom)); box-shadow: none; }
.foot.line .foot-in { justify-content: center; gap: 0 12px; }
.foot.line a, .foot.line .foot-b { font-size: var(--t-12); color: var(--muted); }

/* ui/c/ring.css */
/* The progress ring (M1) and the tick (M2). The arc's offset eases linearly to each new estimate over the poll
   interval (--poll), so the ring moves without steps. The sweep is the one ambient motion; it stops under reduced motion. */
.ring { --poll: 3s; position: relative; display: block; width: 64px; height: 64px; }
.ring svg { width: 100%; height: 100%; overflow: visible; }
.ring .rg-g { transform-origin: 24px 24px; transform-box: view-box; }
.rg-track { fill: oklch(100% 0 0 / 0.2); stroke: oklch(100% 0 0 / 0.42); stroke-width: 3.5; }
.rg-arc { fill: none; stroke: var(--violet); stroke-width: 3.5; stroke-linecap: round; stroke-dasharray: 100 100; stroke-dashoffset: var(--off);
  rotate: -90deg; transform-origin: 24px 24px; transform-box: view-box; filter: drop-shadow(0 0 4px color-mix(in oklch, var(--violet) 55%, transparent));
  transition: stroke-dashoffset calc(var(--poll) * var(--motion-scale)) linear, stroke var(--d-move); }
.ring.fail .rg-arc { stroke: var(--bad); filter: none; }
/* done and fail move by script (M2, M3), so the poll's long ease stays off them */
.ring.done .rg-arc, .ring.fail .rg-arc { transition: none; }
.ring.done .rg-arc { stroke: var(--mint-deep); }
.rg-sweep { fill: none; stroke: oklch(100% 0 0 / 0.95); stroke-width: 3.5; stroke-linecap: round; stroke-dasharray: 9 91; opacity: 0;
  rotate: -90deg; transform-origin: 24px 24px; transform-box: view-box; }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .rg-sweep { animation: rg-sweep calc(2.4s * max(var(--motion-scale), 1)) var(--ease-out) infinite; }
}
@keyframes rg-sweep { 0% { stroke-dashoffset: 100; opacity: 0; } 15% { opacity: 0.9; } 70% { opacity: 0.6; } 100% { stroke-dashoffset: 0; opacity: 0; } }
.ring.wait .rg-arc { opacity: 0; }
.rg-tick { opacity: 0; transform-origin: 24px 24px; transform-box: view-box; }
.rg-disc { fill: var(--mint-deep); transform-origin: 24px 24px; transform-box: view-box; }
.rg-check { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 0; }

/* ui/c/player.css */
/* Player. data-play on the element: poster, loading, preview (muted, on hover), playing, paused, ended, error. */
ts-player { display: block; position: relative; }
.pl { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--r-poster); background: var(--film); isolation: isolate; }
.pl-poster, .pl-v { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pl-poster.none { background: linear-gradient(135deg, var(--page-deep), var(--hair)); }
.pl-v { opacity: 0; transition: opacity var(--d-fade) var(--ease-out); }
ts-player:is([data-play="preview"], [data-play="playing"], [data-play="paused"]) .pl-v { opacity: 1; }
.pl-big { position: absolute; inset: 0; display: grid; place-items: center; z-index: 2; color: #fff; }
.pl-disc { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: oklch(18% 0.01 285 / 0.42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.25); transition: scale var(--d-quick) var(--ease-spring), opacity var(--d-quick) var(--ease-out), background-color var(--d-quick); }
.pl-disc .i { width: 18px; height: 18px; }
.pl-i-play { translate: 1px 0; }
.pl-i-pause, ts-player[data-play="playing"] .pl-i-play { display: none; }
ts-player[data-play="playing"] .pl-i-pause { display: block; }
@media (hover: hover) { .pl-big:hover .pl-disc { scale: 1.06; background: oklch(18% 0.01 285 / 0.55); } }
ts-player[data-play="preview"] .pl-disc, ts-player[data-play="playing"]:not(:hover) .pl-disc { opacity: 0; scale: 0.9; }
ts-player[data-play="loading"] .pl-disc .i, ts-player.buffering .pl-disc .i { visibility: hidden; }
ts-player[data-play="loading"] .pl-disc::after, ts-player.buffering .pl-disc::after { content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%; border: 2px solid #fff; border-right-color: transparent; }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) ts-player[data-play="loading"] .pl-disc::after, html:not([data-motion="reduce"]) ts-player.buffering .pl-disc::after { animation: ts-spin calc(800ms * max(var(--motion-scale), 1)) linear infinite; }
}
.pl-time { position: absolute; z-index: 3; right: 8px; bottom: 8px; padding: 2px 7px; border-radius: 7px; background: oklch(18% 0.01 285 / 0.62); color: #fff;
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums lining-nums; pointer-events: none; }
.pl-err { position: absolute; inset: auto 12px 12px; z-index: 3; padding: 8px 12px; border-radius: 10px; background: oklch(18% 0.01 285 / 0.75); color: #fff; font-size: var(--t-13); }
ts-player[data-play="error"] .pl-poster { filter: grayscale(0.7) brightness(0.6); }

/* Large: the control bar under the picture */
ts-player.large .pl { border-radius: var(--r-ctl) var(--r-ctl) 0 0; }
ts-player.large .pl-disc { width: 64px; height: 64px; }
ts-player.large .pl-disc .i { width: 24px; height: 24px; }
.pl-bar { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 0 14px 0 4px; min-height: 48px; border-radius: 0 0 14px 14px;
  background: var(--film); color: #fff; }
.pl-pp { display: grid; place-items: center; width: 44px; height: 44px; color: #fff; }
.pl-pp .i { width: 18px; height: 18px; }
.pl-seek { width: 100%; height: 44px; margin: 0; background: transparent; accent-color: var(--violet); cursor: pointer; }
.pl-clock { font-size: var(--t-13); font-variant-numeric: tabular-nums lining-nums; color: oklch(100% 0 0 / 0.82); white-space: nowrap; }

/* ui/c/card-frame.css */
/* The card frame shared by the clip card and the take card (plan 12.1: one frame): a header row, the picture,
   the text and a foot row. Selection (M12) moves a 2 px violet ring onto the card and drops a "Selected" tag in
   from above its top edge. */
.cf { position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 8px var(--pad-inner) 2px; border-radius: var(--r-card); background: var(--surface);
  box-shadow: var(--shadow-sm); transition: box-shadow var(--d-quick) var(--ease-out), translate var(--d-quick) var(--ease-out); }
.cf-h { display: flex; align-items: center; gap: 8px; min-height: 30px; min-width: 0; }
.cf-h > .chip { flex: none; }
.cf-id { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-family: var(--font-heading); font-weight: 650; font-size: var(--t-17); line-height: 1; letter-spacing: -0.01em; font-variant-numeric: lining-nums; white-space: nowrap; }
.cf-sp { flex: 1; }
.cf-h .btn.icon { margin: -6px -8px -6px 0; color: var(--ink-2); }
/* a clip card at the planner's take width (168 px): the 44 px target reaches past the icon into the gap beside it, so the id keeps its width */
ts-clip-card .cf-h .btn.icon { margin-left: -8px; }
.cf-pic { position: relative; border-radius: var(--r-poster); }
.cf-t { font-size: var(--t-13); line-height: 1.4; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cf-f { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 34px; margin: -7px -8px -4px 0; }
.cf-cost { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-15); font-variant-numeric: tabular-nums lining-nums; color: var(--ink); }
.cf-cost.none { color: var(--faint); }
.cf-why { font-size: var(--t-13); font-weight: 500; color: var(--bad); }
/* a reason shows its whole text, wrapped */
.cf-f .cf-why { flex: 1; min-width: 0; line-height: 1.35; }
.cf.sel { box-shadow: 0 0 0 2px var(--violet), 0 10px 26px -14px color-mix(in oklch, var(--violet-ink) 50%, transparent); }
.cf-tag { position: absolute; z-index: 4; top: -11px; left: 50%; translate: -50% 0; padding: 2px 10px; border-radius: 8px; background: var(--surface); color: var(--violet-ink);
  font-size: 12px; font-weight: 650; box-shadow: 0 0 0 1.5px var(--violet); white-space: nowrap; }
@media (hover: hover) { .cf.hit:hover { box-shadow: 0 0 0 1px color-mix(in oklch, var(--violet) 35%, transparent), 0 8px 20px -10px color-mix(in oklch, var(--violet-ink) 30%, transparent); } .cf.sel.hit:hover { box-shadow: 0 0 0 2px var(--violet), 0 10px 26px -14px color-mix(in oklch, var(--violet-ink) 50%, transparent); } }
/* The picture's placeholder before a clip is made: the plan's reference image dimmed, else a soft wash */
.cf-ph { position: absolute; inset: 0; z-index: 1; overflow: hidden; border-radius: var(--r-poster); background: linear-gradient(140deg, oklch(93% 0.02 286), oklch(88% 0.03 280)); }
.cf-ph img { width: 100%; height: 100%; object-fit: cover; opacity: 0.38; filter: grayscale(0.35) saturate(0.8); }
.cf-ph.blur img { filter: blur(10px) saturate(1.1); opacity: 0.85; scale: 1.15; }
.cf-ph.blur::after { content: ""; position: absolute; inset: 0; background: linear-gradient(160deg, color-mix(in oklch, var(--violet) 28%, transparent), oklch(25% 0.05 280 / 0.35)); }
.cf-ph .cf-len { position: absolute; right: 8px; bottom: 8px; padding: 2px 7px; border-radius: 7px; background: oklch(100% 0 0 / 0.75); color: var(--ink-2); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.cf-ring { position: absolute; inset: 0; z-index: 3; display: grid; place-items: center; pointer-events: none; }
.cf-pic .pl-big { z-index: 2; }
/* Cards are never dragged: their pictures and videos lift no ghost image and leave the gesture to the page */
.cf img, .cf video { -webkit-user-drag: none; }

/* ui/c/clip-card.css */
/* Clip card: the frame, a full-card hit area under its controls, the ring over the picture */
ts-clip-card { display: flex; flex-direction: column; }
ts-clip-card .cf-hit { position: absolute; inset: 0; z-index: 0; border-radius: inherit; }
ts-clip-card .cf-h, ts-clip-card .cf-f, ts-clip-card .cf-t, ts-clip-card .cf-why { position: relative; z-index: 1; pointer-events: none; }
ts-clip-card .cf-h > *, ts-clip-card .cf-f > * { pointer-events: auto; }
ts-clip-card .cf-h > .chip, ts-clip-card .cf-h > .cf-id, ts-clip-card .cf-f > .cf-cost { pointer-events: none; }
ts-clip-card .cf-pic { z-index: 1; }
ts-clip-card.queued .cf-pic, ts-clip-card.running .cf-pic, ts-clip-card.not_made .cf-pic, ts-clip-card.cancelled .cf-pic { aspect-ratio: 16 / 9; pointer-events: none; }
ts-clip-card.not_made .cf-ph img, ts-clip-card.cancelled .cf-ph img { opacity: 0.22; }
ts-clip-card.not_made .cf-ph { background: linear-gradient(140deg, var(--bad-soft), oklch(93% 0.02 20)); }
ts-clip-card.cancelled .cf-ph { background: var(--ph-spare); }
ts-clip-card .cf-dl .i { width: 18px; height: 18px; }
ts-clip-card .cf-menu .mn-trig { color: var(--muted); }
.cf-cost.none { color: var(--faint); }
ts-clip-card.not_made .cf-cost, ts-clip-card.cancelled .cf-cost { text-decoration: line-through; text-decoration-thickness: 1px; }
/* Showcase (a public page's films row, after waitlist-gpt-1): the picture flush to the card's top and sides at 10:7,
   its top corners the card's; then the title in deep violet, a line and the meta line with dot separators. The play
   disc and the length chip are near-opaque. The meta line sits at the card's foot, so cards of a row line their meta up. */
ts-clip-card.showcase { gap: 0; padding: 0 0 13px; overflow: clip; }
ts-clip-card.showcase > :not(.cf-pic) { margin-inline: 17px; }
ts-clip-card.showcase .cf-pic, ts-clip-card.showcase .cf-pic .pl, ts-clip-card.showcase .cf-still { border-radius: var(--r-card) var(--r-card) 0 0; }
ts-clip-card.showcase .cf-pic .pl, ts-clip-card.showcase .cf-still { aspect-ratio: 10 / 7; }
ts-clip-card.showcase .cf-still { display: block; width: 100%; object-fit: cover; }
ts-clip-card.showcase .cf-id { margin-top: 12px; font-size: var(--t-20); font-weight: 500; line-height: 1.25; color: var(--violet-deep, var(--violet-ink)); }
ts-clip-card.showcase .cf-t { margin-top: 6px; font-size: 14px; color: var(--ink-2); }
ts-clip-card.showcase .cf-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; margin-top: auto; padding-top: 14px; font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums lining-nums; }
ts-clip-card.showcase .cf-meta > span + span::before { content: ""; display: inline-block; vertical-align: middle; width: 3px; height: 3px; margin: -2px 12px 0 0; border-radius: 50%; background: var(--hair-2); }
ts-clip-card.showcase .pl-disc { background: oklch(18% 0.01 285 / 0.85); }
ts-clip-card.showcase .pl-disc .i { width: 32px; height: 32px; }
ts-clip-card.showcase .pl-time { right: 9px; bottom: 8px; padding: 2px 8px; border-radius: 6px; background: oklch(15% 0.01 285 / 0.85); font-size: var(--t-13); font-weight: 500; }
@media (max-width: 599px) {
  ts-clip-card.showcase .cf-id { font-size: var(--t-17); }
  ts-clip-card.showcase { padding-bottom: 22px; }
  ts-clip-card.showcase .cf-id { margin-top: 16px; }
  ts-clip-card.showcase .pl-disc .i { width: 18px; height: 18px; }
  ts-clip-card.showcase .cf-t, ts-clip-card.showcase .cf-meta { font-size: var(--t-13); }
}

/* ui/c/take-card.css */
/* Take card: the tick, the dimming of an unticked take, the last-frame corner */
ts-take-card { display: flex; flex-direction: column; }
ts-take-card .cf-hit { position: absolute; inset: 0; z-index: 0; border-radius: inherit; }
ts-take-card .cf-h, ts-take-card .cf-t, ts-take-card .cf-f { position: relative; z-index: 1; pointer-events: none; }
ts-take-card .cf-h > .tk-tick { pointer-events: auto; }
ts-take-card .cf-pic { z-index: 1; aspect-ratio: 16 / 9; overflow: hidden; pointer-events: none; }
ts-take-card.pick .cf-pic { pointer-events: auto; }
ts-take-card .tk-img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--r-poster); }
/* a take still to make shows the sketch it starts from at full strength, with no wash over it (the tick says it is still to make) */
ts-take-card:not(.pick) .cf-ph:not(.blur):has(> img) { background: none; }
ts-take-card:not(.pick) .cf-ph:not(.blur) img { opacity: 1; filter: none; }
ts-take-card .dim { transition: opacity var(--d-quick) var(--ease-out), filter var(--d-quick) var(--ease-out); }
/* the prompt is dimmable too: its own transition keeps the opening and closing of its lines (.tk-prompt below) */
ts-take-card .tk-prompt.dim { transition: opacity var(--d-quick) var(--ease-out), filter var(--d-quick) var(--ease-out), max-height var(--d-move) var(--ease-out), -webkit-line-clamp var(--d-move) step-end allow-discrete; }
ts-take-card.sel .tk-prompt.dim { transition: opacity var(--d-quick) var(--ease-out), filter var(--d-quick) var(--ease-out), max-height var(--d-move) var(--ease-out), -webkit-line-clamp 0s allow-discrete; }
ts-take-card.off .dim { opacity: 0.42; filter: grayscale(0.6); }
.tk-tick { display: grid; place-items: center; width: 44px; height: 44px; margin: -8px -6px -8px -12px; }
.tk-box { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 7px; background: var(--violet); color: #fff; transition: background-color var(--d-tap), box-shadow var(--d-tap); }
.tk-box .i { width: 15px; height: 15px; stroke-width: 2.4; transition: opacity var(--d-tap), scale var(--d-quick) var(--ease-spring); }
.tk-tick[aria-checked="false"] .tk-box { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair-2); }
.tk-tick[aria-checked="false"] .tk-box .i { opacity: 0; scale: 0.6; }
.tk-name { display: grid; gap: 1px; min-width: 0; }
.tk-name .cf-id { font-family: var(--sans); font-size: var(--t-15); font-weight: 650; letter-spacing: 0; }
.tk-dot::before { content: ""; display: inline-block; width: 3px; height: 3px; margin: 0 6px; border-radius: 50%; background: currentColor; vertical-align: middle; }
.tk-diff { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The prompt shows three lines; the selected take shows all of it (the real planner's .t-text): the clamp goes and
   max-height opens from three lines to the whole text, so the card grows and the cards under it follow */
.tk-prompt { -webkit-line-clamp: 3; line-clamp: 3; max-height: 3lh; min-height: 2lh; color: var(--ink); interpolate-size: allow-keywords;
  transition: max-height var(--d-move) var(--ease-out), -webkit-line-clamp var(--d-move) step-end allow-discrete; }
ts-take-card.sel .tk-prompt { -webkit-line-clamp: none; line-clamp: none; max-height: max-content; transition: max-height var(--d-move) var(--ease-out), -webkit-line-clamp 0s allow-discrete; }
/* A take with no prompt says so in full, wrapped */
.tk-none { color: var(--bad); font-weight: 550; -webkit-line-clamp: none; line-clamp: none; max-height: none; }
ts-take-card.bad { box-shadow: 0 0 0 2px var(--bad), 0 10px 26px -14px oklch(54% 0.16 25 / 0.45); }
.tk-len { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
ts-take-card:not(.pick) .tk-len { font-size: var(--t-15); font-weight: 600; color: var(--ink); }
.tk-f { min-height: 24px; }
/* A made take: its still with a play mark and its length on it, and a "Made" tag in the header; no length in the foot */
ts-take-card:has(.tk-play) .cf-f { display: none; }
.tk-play { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; pointer-events: none; }
.tk-play .i { box-sizing: content-box; width: 16px; height: 16px; padding: 11px; border-radius: 50%; background: oklch(18% 0.01 285 / 0.42); color: #fff;
  box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.25); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.tk-time { position: absolute; z-index: 3; right: 6px; bottom: 6px; padding: 1px 6px; border-radius: 6px; background: oklch(18% 0.01 285 / 0.62); color: #fff; font-size: 12px; font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums; pointer-events: none; }
.tk-made { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--mint-soft); color: var(--mint-ink); white-space: nowrap; }
ts-take-card.compact .tk-play .i { width: 11px; height: 11px; padding: 7px; }
ts-take-card.compact .tk-time { right: 4px; bottom: 4px; padding: 0 5px; font-size: 11px; }
.tk-last { position: absolute; z-index: 3; right: 8px; top: 8px; width: 30%; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden; box-shadow: 0 0 0 2px var(--surface), 0 4px 10px -4px oklch(20% 0.03 285 / 0.5); }
.tk-last img { width: 100%; height: 100%; object-fit: cover; }
ts-take-card.pick .cf-h { min-height: 40px; }
/* A take just added on the planner: dashed violet, with its tag */
ts-take-card.fresh { background: color-mix(in oklch, var(--violet-soft) 22%, var(--surface)); box-shadow: none; outline: 1.5px dashed color-mix(in oklch, var(--violet) 70%, transparent); outline-offset: -1.5px; }
/* while its editor is open it stays dashed, the dash heavier, with no selection ring under it */
ts-take-card.fresh.sel { outline-style: dashed; outline-width: 2px; outline-offset: -2px; box-shadow: none; }
ts-take-card.fresh .tk-none { color: var(--violet-ink); font-weight: 500; }
.tk-new { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--violet-soft); color: var(--violet-ink); white-space: nowrap; }
/* A comparison take its model cannot make at its length: dimmed, its reason in place of the length */
ts-take-card.out .dim { opacity: 0.42; filter: grayscale(0.8); }
ts-take-card.out .tk-f { opacity: 1; filter: none; }
.tk-out { font-size: 12.5px; font-weight: 550; color: var(--warn-ink); }
.tk-note { font-size: 12.5px; color: var(--muted); }
/* Compact (the scene diagram's several-take shots): the tick, id and length on the left of the picture, the prompt under
   them at the card's full width */
ts-take-card.compact { display: grid; grid-template-columns: minmax(0, 1fr) 88px; grid-template-rows: auto auto auto; column-gap: 10px; row-gap: 2px; padding: 4px 8px 6px var(--pad-inner); }
ts-take-card.compact > .cf-h { grid-column: 1; grid-row: 1; min-height: 28px; }
ts-take-card.compact > .cf-f { grid-column: 1; grid-row: 2; align-self: start; min-height: 20px; margin: 0; }
ts-take-card.compact > .cf-pic { grid-column: 2; grid-row: 1 / span 2; align-self: start; aspect-ratio: 16 / 9; margin-top: 2px; }
ts-take-card.compact > .cf-t { grid-column: 1 / -1; grid-row: 3; min-height: 1lh; }
/* the last frame stays as a small inset in the corner of the compact picture */
ts-take-card.compact .tk-last { right: 4px; top: 4px; width: 40%; border-radius: 4px; box-shadow: 0 0 0 1.5px var(--surface); }
ts-take-card.compact .tk-new { padding: 0 6px; }
/* Image-led (the scene diagram's one-take shots): the picture on top at the card's full width, then the id with its tick, three lines of prompt and the length */
ts-take-card:is(.led, .tile) { gap: 2px; padding: 0 0 2px; }
ts-take-card:is(.led, .tile) > .cf-pic { order: -1; }
ts-take-card:is(.led, .tile) > .cf-pic, ts-take-card:is(.led, .tile) .cf-ph, ts-take-card:is(.led, .tile) .tk-img { border-radius: var(--r-card) var(--r-card) 0 0; }
ts-take-card:is(.led, .tile) > .cf-h { margin-top: 2px; padding: 0 var(--pad-inner); }
ts-take-card:is(.led, .tile) > .cf-t { padding: 0 var(--pad-inner); min-height: 1lh; }
ts-take-card:is(.led, .tile) > .cf-f { margin: 0; padding: 0 var(--pad-inner); }
/* Tile (the comparison grid's cells): the page's subtle surface, a small label, no foot unless the take is out */
ts-take-card.tile { background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair); }
ts-take-card.tile.sel { box-shadow: 0 0 0 2px var(--violet), var(--shadow-sm); }
ts-take-card.tile > .cf-h { min-height: 36px; }
ts-take-card.tile .tk-lab { font-family: var(--sans); font-size: var(--t-13); font-weight: 600; letter-spacing: 0; color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums; }
ts-take-card.tile .tk-lab .tk-dot::before { margin: 0 5px; }
ts-take-card.tile > .cf-f:not(:has(.tk-out, .tk-note)) { display: none; }
ts-take-card.tile .cf-ph { background: color-mix(in oklch, var(--page-deep) 60%, var(--wash)); }
.tk-frame { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; color: var(--faint); pointer-events: none; }
.tk-frame .i { width: 28px; height: 28px; stroke-width: 1.4; }
/* Focus is a lighter ring further out, so it never reads as the selection */
ts-take-card .cf-hit:focus-visible { outline: 2px solid color-mix(in oklch, var(--violet) 60%, transparent); outline-offset: 3px; }
/* What a queued take starts from: its references as up to four small thumbnails in the picture's place */
.tk-refs { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 3px; padding: 3px;
  border-radius: var(--r-poster); background: color-mix(in oklch, var(--page-deep) 70%, var(--surface)); }
.tk-ref { width: 100%; height: 100%; min-height: 0; object-fit: cover; border-radius: 6px; }
.tk-ref.more { display: grid; place-items: center; background: var(--surface); color: var(--ink-2); font-size: 12px; font-weight: 650; font-variant-numeric: tabular-nums; }
ts-take-card:is(.led, .tile) .tk-refs { border-radius: var(--r-card) var(--r-card) 0 0; }
.tk-refs[data-n="2"] { grid-template-rows: minmax(0, 1fr); }
.tk-refs[data-n="3"] > .tk-ref:first-child { grid-row: span 2; }
/* Text only: no picture; the prompt leads the card, and a quiet mark says what it starts from */
.tk-mode { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px 0 6px; border-radius: 999px; background: var(--wash); color: var(--muted); font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.tk-mode .i { width: 13px; height: 13px; }
ts-take-card.compact.text-led { grid-template-columns: minmax(0, 1fr); }
ts-take-card.led.text-led { padding-top: 6px; }
ts-take-card.led.text-led > .cf-h { margin-top: 0; }
/* Selected and widened on the scene diagram (from 600 px), a led take reads as the compact one: the id above, the
   picture at its rest width on the left with the length under it, the whole prompt in the column to its right, so it
   runs across the width and less far down. The prompt is laid out at its final width from the start and the card clips
   it as it widens (overflow-x), so its height only grows; while the card narrows again the picture keeps its rest width */
@media (min-width: 600px) {
  ts-scene-diagram ts-take-card.led > .cf-pic { max-width: var(--take-w); }
  ts-scene-diagram ts-take-card.led.sel { display: grid; grid-template-columns: var(--take-w) minmax(0, 1fr); grid-template-rows: auto auto 1fr;
    column-gap: 12px; row-gap: 4px; padding: 6px var(--pad-inner) 10px; overflow-x: clip; }
  ts-scene-diagram ts-take-card.led.sel > .cf-h { grid-column: 1 / -1; grid-row: 1; margin: 0; padding: 0; }
  ts-scene-diagram ts-take-card.led.sel > .cf-pic { grid-column: 1; grid-row: 2; align-self: start; }
  ts-scene-diagram ts-take-card.led.sel > .cf-pic, ts-scene-diagram ts-take-card.led.sel :is(.cf-ph, .tk-img, .tk-refs) { border-radius: var(--r-poster); }
  ts-scene-diagram ts-take-card.led.sel > .cf-f { grid-column: 1; grid-row: 3; align-self: start; padding: 0; }
  ts-scene-diagram ts-take-card.led.sel > .cf-t { grid-column: 2; grid-row: 2 / span 2; padding: 0; width: calc(var(--sel-w, 420px) - var(--take-w) - 12px - 2 * var(--pad-inner)); }
  ts-scene-diagram ts-take-card.led.sel.text-led > .cf-t { grid-column: 1 / -1; grid-row: 2; width: calc(var(--sel-w, 420px) - 2 * var(--pad-inner)); }
  /* The selected compact take (a shot with several takes, or the one open on load) reads the same: the id above, the picture
     at its rest width on the left with the length under it, the whole prompt to its right */
  ts-scene-diagram ts-take-card.compact.sel:not(.text-led) { grid-template-columns: 88px minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: 12px; overflow-x: clip; }
  ts-scene-diagram ts-take-card.compact.sel:not(.text-led) > .cf-h { grid-column: 1 / -1; grid-row: 1; }
  ts-scene-diagram ts-take-card.compact.sel:not(.text-led) > .cf-pic { grid-column: 1; grid-row: 2; margin-top: 0; }
  ts-scene-diagram ts-take-card.compact.sel:not(.text-led) > .cf-f { grid-column: 1; grid-row: 3; }
  ts-scene-diagram ts-take-card.compact.sel:not(.text-led) > .cf-t { grid-column: 2; grid-row: 2 / span 2; width: calc(var(--sel-wc, 500px) - 88px - 12px - var(--pad-inner) - 8px); }
}

/* ui/c/plan-group.css */
/* Plan group: the header, then the clips in a row (scene) or a prompt × model grid (comparison) */
ts-plan-group { display: block; --card-w: 168px; }
@media (max-width: 599px) { ts-plan-group { --card-w: calc(100vw - 2 * var(--gutter) - 32px); } }
.pgp { padding: 14px 0 14px; border-radius: var(--r-page); }
.pgp-h { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 0 var(--pad-card); min-height: 44px; }
.pgp-mark { flex: none; width: 12px; height: 12px; border-radius: 4px; background: var(--hue); box-shadow: inset 0 0 0 1px oklch(25% 0.03 285 / 0.08); }
.pgp-name { min-width: 0; }
.pgp-sp { flex: 1; }
.pgp-cost { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-13); color: var(--muted); }
/* The divider between Cost and Hide (the concept's: 22 px tall, a hairline, 17 px from the figure and from the label). Price, divider and Hide share one centre line, measured on the glyph ink (check.py) */
.pgp-r { display: inline-flex; align-items: center; margin-left: auto; }
.pgp-div { flex: none; align-self: center; width: 1px; height: 22px; margin-left: 17px; background: var(--hair); }
.pgp-cv { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-17); color: var(--ink); }
.btn.pgp-tg { gap: 4px; padding: 0 8px 0 0; margin-left: 17px; }
.pgp-cost + .btn.pgp-tg { margin-left: 0; }
.pgp-div + .btn.pgp-tg { margin-left: 17px; }
.pgp-chev { width: 16px; height: 16px; rotate: 180deg; transition: rotate var(--d-move) var(--ease-out); }
.pgp-tg[aria-expanded="false"] .pgp-chev { rotate: 0deg; }
@media (max-width: 599px) { .pgp-h { padding: 0 16px; } .pgp-h .chip.kind { display: none; } }
/* On a phone the header is one row: the plan's name, then Cost and Hide at the right (the count is in the summary card) */
@media (max-width: 599px) {
  ts-plan-group { min-width: 0; }
  .pgp-h:not(.q) { flex-wrap: nowrap; gap: 8px; }
  .pgp-h:not(.q) .pgp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .pgp-h:not(.q) :is(.chip.count, .pgp-sp) { display: none; }
  .pgp-h:not(.q) .pgp-div { margin-left: 8px; }
  .pgp-h:not(.q) .pgp-div + .btn.pgp-tg { margin-left: 8px; }
  .pgp-h:not(.q) .pgp-r { flex: none; }
}

.pgp-bw { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--d-move) var(--ease-out), opacity var(--d-quick) var(--ease-out); }
.pgp-bw.shut { grid-template-rows: 0fr; opacity: 0; }
.pgp-b { min-height: 0; overflow: hidden; }
.pgp-row { display: flex; align-items: flex-start; padding: 10px var(--pad-card) 4px; scroll-padding-inline: var(--pad-card); }
.pgp-row > ts-clip-card { flex: 0 0 var(--card-w); }
/* The branch line between two cards, at the picture's middle */
.pgp-link { position: relative; flex: 0 0 28px; }
.pgp-link::before { content: ""; position: absolute; left: -2px; right: -2px; top: calc(8px + 30px + 6px + (var(--card-w) - 24px) * 9 / 32); height: 2px; border-radius: 1px;
  background: color-mix(in oklch, var(--branch) 55%, var(--hair-2)); transition: background-color var(--d-move); }
.pgp-link.on::before { background: var(--branch); }
.pgp-link i { position: absolute; z-index: 1; left: 50%; top: calc(8px + 30px + 6px + (var(--card-w) - 24px) * 9 / 32 + 1px); width: 10px; height: 10px; translate: -50% -50%; border-radius: 50%;
  background: var(--surface); box-shadow: inset 0 0 0 2px var(--branch); }
@media (max-width: 599px) { .pgp-row { padding: 14px 16px 6px; } .pgp-link { flex-basis: 20px; } }
/* a short phone: the group's top and the clip row start sooner, so the first clip shows above the fixed bar */
@media (max-width: 599px) and (max-height: 760px) { .pgp { padding-top: 6px; } .pgp-row { padding-top: 6px; } }

.pgp-cmp { display: grid; gap: var(--gap); padding: 8px 0 4px; }
.pgp-prow { display: flex; align-items: flex-start; gap: var(--gap); padding: 2px var(--pad-card) 4px; scroll-padding-inline: var(--pad-card); }
.pgp-prow > .pgp-pcard, .pgp-trow > ts-clip-card { flex: 0 0 var(--card-w); }
.pgp-trow { display: contents; }
/* The prompt: a card like the clip cards (same radius, border and elevation), labelled, first in its row */
.pgp-pcard { align-self: stretch; align-content: start; }
.pgp-prompt { font-size: var(--t-13); line-height: 1.45; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; }
/* Under 600 px the prompt card sits above its row of takes, full width; the takes scroll sideways under it on their own */
@media (max-width: 599px) {
  .pgp-prow { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; overflow: visible; padding-inline: 0; scroll-snap-type: none; }
  .pgp-pcard { margin-inline: var(--pad-card); flex: none; }
  .pgp-trow { display: flex; gap: var(--gap); padding: 0 var(--pad-card) 4px; scroll-padding-inline: var(--pad-card); }
}
/* The header on the Confirm sheet's plan list: a tick, then the plan's Expected in a fixed column */
.pgp-h.q { flex-wrap: nowrap; gap: 8px; padding: 0; }
.pgp-tick { margin: -8px -8px -8px -12px; }
.pgp-tick[disabled] { cursor: default; opacity: 0.55; }
.pgp-h.q .pgp-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pgp-q { display: inline-grid; grid-template-columns: var(--q-col, 72px); flex: none; }
.pgp-qv { text-align: right; font-family: var(--font-figure); font-weight: 600; font-size: var(--t-17); font-variant-numeric: tabular-nums lining-nums; color: var(--ink); white-space: nowrap; }
@media (max-width: 599px) { .pgp-h.q .chip.kind { display: none; } .pgp-q { --q-col: 64px; } }

/* ui/c/shot-strip.css */
/* Shot strip */
ts-shot-strip { display: block; position: relative; padding: 14px 16px 16px; border-radius: var(--r-page); }
.ss-h { display: flex; align-items: center; gap: 4px 12px; min-height: 44px; margin-bottom: 8px; }
.ss-count { font-family: var(--font-heading); font-weight: 650; font-size: var(--t-17); }
.ss-len { font-size: var(--t-13); color: var(--muted); font-variant-numeric: tabular-nums lining-nums; }
.ss-sp { flex: 1; }
.ss-play { width: 44px; padding: 0; border-radius: 50%; color: var(--violet-ink); }
.ss-play .i { width: 16px; height: 16px; }
.ss-play.on { background: var(--violet); color: #fff; box-shadow: none; }
.ss-row { display: flex; gap: 8px; padding-bottom: 2px; }
.ss-b { position: relative; flex: 0 0 116px; aspect-ratio: 16 / 9; border-radius: 9px; overflow: hidden; background: var(--page-deep); box-shadow: inset 0 0 0 1px var(--hair);
  transition: box-shadow var(--d-quick) var(--ease-out), opacity var(--d-quick); }
.ss-b img { width: 100%; height: 100%; object-fit: cover; }
.ss-b.out { background: var(--ph-spare); }
.ss-b.now { box-shadow: 0 0 0 2px var(--violet), 0 6px 16px -8px color-mix(in oklch, var(--violet-ink) 60%, transparent); }
.ss-n { position: absolute; left: 5px; top: 5px; min-width: 22px; height: 22px; padding: 0 6px; display: grid; place-items: center; border-radius: 7px; background: var(--violet); color: #fff;
  font-family: var(--font-heading); font-weight: 650; font-size: 13px; font-variant-numeric: lining-nums; }
.ss-b.out .ss-n { background: var(--surface); color: var(--muted); box-shadow: inset 0 0 0 1px var(--hair-2); }
.ss-t { position: absolute; right: 5px; bottom: 5px; display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--mint-deep); color: #fff; box-shadow: 0 0 0 2px oklch(100% 0 0 / 0.85); }
.ss-t .i { width: 13px; height: 13px; stroke-width: 2.6; }
@media (max-width: 599px) { .ss-b { flex-basis: 92px; } }
/* Trim: block widths by length, a playhead over them */
.ss-row.trim { gap: 3px; height: 54px; }
.ss-row.trim .ss-b { flex: 1 1 0; min-width: 6px; aspect-ratio: auto; height: 100%; border-radius: 6px; transition: flex-grow var(--d-slow) var(--ease-spring), box-shadow var(--d-quick); }
.ss-row.trim .ss-b.out { display: none; }
.ss-row.trim .ss-n { left: 4px; top: 4px; min-width: 18px; height: 18px; font-size: 11.5px; border-radius: 6px; }
.ss-head { position: absolute; left: calc(16px + (100% - 32px) * var(--at) / 100); bottom: 12px; width: 2px; height: 62px; border-radius: 1px; background: var(--ink);
  box-shadow: 0 0 0 2px oklch(100% 0 0 / 0.7); transition: left calc(1s * var(--motion-scale)) linear; }

/* ui/c/timeline.css */
/* Timeline: groups (the phases, then each plan) of segments, then spare time to the cap */
ts-timeline { display: block; }
.tl-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin-bottom: 12px; }
.tl-sub { display: inline-flex; align-items: baseline; gap: 10px; font-size: var(--t-15); color: var(--muted); font-variant-numeric: tabular-nums lining-nums; }
.tl-strong { color: var(--ink-2); font-weight: 600; }
.tl-sep { width: 1px; height: 14px; background: var(--hair-2); align-self: center; }
.tl-sp { flex: 1; }
.tl-h { min-height: 30px; align-items: center; }
.tl-h.c { min-height: 28px; }
/* Live: the header's right side, with the failed chip beside the time left */
.tl-live { flex-wrap: wrap; justify-content: flex-end; }
.tl-fail { align-self: center; height: 22px; padding: 0 9px; }
.tl-bar { display: flex; align-items: flex-end; gap: 6px; }
.tl-g { display: grid; gap: 6px; min-width: 0; flex-basis: 0; flex-shrink: 1; }
.tl-g.plan + .tl-g.plan { margin-left: 4px; }
.tl-gl { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The last plan's label may run on over the spare time to its right */
.tl-g.plan:has(+ .tl-g:not(.plan)) .tl-gl, .tl-g.plan:last-child .tl-gl { overflow: visible; text-overflow: clip; }
.tl-gl::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 3px; background: var(--hue); }
.tl-segs { display: flex; gap: 3px; height: 30px; }
.tl-s { position: relative; flex: 1 1 0; min-width: 3px; border-radius: 4px; background: var(--c, var(--page-deep)); transform-origin: left center;
  transition: background-color var(--d-move) var(--ease-out), box-shadow var(--d-move) var(--ease-out), flex-grow var(--d-slow) var(--ease-spring); }
.tl-g:first-child .tl-s:first-child { border-radius: 8px 4px 4px 8px; }
/* Each segment's colour (--c): the phases, the clips, a plan's hue (final) */
.tl-s.ph-start, .tl-dot.ph-start { --c: var(--ph-start); }
.tl-s.ph-download, .tl-dot.ph-download { --c: var(--ph-download); }
.tl-s.ph-load, .tl-dot.ph-load { --c: var(--ph-load); }
.tl-s.clip, .tl-dot.clip { --c: oklch(80% 0.09 330); }
.tl-dot { background: var(--c); }
/* Live: the forecast's bar with the session drawn on it. What is done is at full colour; what is ahead is a tint of its
   colour; the running segment fills to its fraction (--f) as the snapshots arrive */
ts-timeline[data-mode="live"] .tl-s:not(.spare) { --f: 1; background: linear-gradient(var(--c), var(--c)) left / calc(var(--f) * 100%) 100% no-repeat, color-mix(in oklch, var(--c) 30%, var(--surface));
  transition: background-size var(--poll, var(--d-move)) linear, box-shadow var(--d-move) var(--ease-out), flex-grow var(--d-slow) var(--ease-spring); }
ts-timeline[data-mode="live"] .tl-s:is(.queued, .cancelled) { --f: 0; }
ts-timeline[data-mode="live"] .tl-s.cancelled { background: repeating-linear-gradient(-45deg, var(--hair-2) 0 1.5px, transparent 1.5px 6px), color-mix(in oklch, var(--c) 18%, var(--surface)); }
/* A failed clip: its full colour under a red ring and hatch */
ts-timeline[data-mode="live"] .tl-s.not_made { box-shadow: inset 0 0 0 1.5px var(--bad);
  background: repeating-linear-gradient(-45deg, color-mix(in oklch, var(--bad) 45%, transparent) 0 1.5px, transparent 1.5px 5px), var(--c); }
/* The running segment carries a gentle sweep (the one ambient motion with the ring) */
.tl-s.running::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(100deg, transparent 38%, oklch(100% 0 0 / 0.42) 50%, transparent 62%) 100% 0 / 300% 100% no-repeat; }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .tl-s.running::after { animation: tl-run calc(2.4s * max(var(--motion-scale), 1)) var(--ease-out) infinite; }
}
@keyframes tl-run { to { background-position: 0 0; } }
/* The current point: a thin ink line through the bar */
.tl-now { position: absolute; top: -4px; bottom: -4px; left: calc(var(--f) * 100%); width: 2px; margin-left: -1px; border-radius: 1px; background: var(--ink);
  box-shadow: 0 0 0 1.5px var(--surface); transition: left var(--poll, var(--d-move)) linear; }
.tl.compact .tl-now { top: -3px; bottom: -3px; }
.tl-s.spare, .tl-dot.spare { background: var(--ph-spare); box-shadow: inset 0 0 0 1px var(--hair-2); }
.tl-s.spare { border-radius: 4px 8px 8px 4px; }
.tl-s.plan, .tl-dot.plan { --c: var(--hue); }
.tl-cap { display: flex; justify-content: flex-end; margin-top: 6px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.tl-lg { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 12px; font-size: var(--t-13); color: var(--ink-2); }
.tl-lg li { display: inline-flex; align-items: center; gap: 8px; }
.tl-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.tl-v { color: var(--muted); font-variant-numeric: tabular-nums lining-nums; }
.tl-lg.rows { display: grid; gap: 0; }
.tl-lg.rows li { display: grid; grid-template-columns: 9px minmax(0, 1fr) auto; gap: 10px; min-height: 36px; }
.tl-lg.rows li + li { border-top: 1px solid var(--hair); }
.tl-lg.rows .tl-v { color: var(--ink); font-size: var(--t-15); }
/* Compact: a thin bar and a one-line legend */
.tl.compact .tl-h.c { margin-bottom: 8px; }
.tl.compact .tl-segs { height: 10px; gap: 2px; }
.tl.compact .tl-s { border-radius: 3px; }
.tl.compact .tl-bar { gap: 4px; }
.tl.compact .tl-lg { margin-top: 10px; gap: 6px 16px; font-size: 12.5px; }
@media (max-width: 599px) {
  .tl-segs { height: 22px; gap: 2px; }
  .tl-bar { gap: 4px; }
  .tl-lg { gap: 6px 16px; }
}
/* The forecast and live bar (the concept): a 22 px bar, the blocks almost touching */
ts-timeline:is([data-mode="forecast"], [data-mode="live"]):not(.compact) .tl-bar { gap: 4px; }
ts-timeline:is([data-mode="forecast"], [data-mode="live"]):not(.compact) .tl-segs { height: 22px; gap: 2px; }

/* ui/c/events.css */
/* Event list */
ts-events { display: block; }
.ev-t { margin-bottom: 8px; }
.ev { display: grid; }
.ev-li { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 12px; padding: 9px 0; font-size: var(--t-15); line-height: 1.45; }
.ev-li + .ev-li { border-top: 1px solid var(--hair); }
.ev-at { color: var(--muted); font-size: var(--t-13); font-variant-numeric: tabular-nums lining-nums; padding-top: 2px; }
.ev-x { color: var(--ink-2); overflow-wrap: anywhere; }
.ev-li:first-child .ev-x { color: var(--ink); font-weight: 500; }

/* ui/c/money-tween.css */
/* Money tween: the lead amount and its breakdown; the counting overlay sits exactly over the figure */
ts-money-tween { display: grid; gap: 16px; }
.mt-fig { position: relative; display: inline-block; border-radius: 8px; }
.mt-v { position: relative; display: inline-block; text-align: right; font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.mt-lead .mt-v { text-align: left; }
.mt-v.tweening { -webkit-text-fill-color: transparent; }
.mt-ov { position: absolute; top: 0; right: 0; -webkit-text-fill-color: currentcolor; white-space: nowrap; pointer-events: none; }
.mt-lead .mt-ov { left: 0; right: auto; }
.mt-rows { display: grid; }
.mt-row .v { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-17); }

/* ui/c/spend-card.css */
/* Spend card: figures and short labels only. The key amount on the left, Expected / Cap / Held in a row beside it, the meter under. */
ts-spend-card { display: grid; gap: 14px; align-content: center; padding: 14px var(--pad-card) 16px; isolation: isolate; overflow: hidden; }
/* One fixed layout for every state: the key figure, then three slots of fixed width. Ended, Back and Held take the first two. */
.sp-top { display: grid; gap: 10px; }
.sp-key .l { gap: 8px; }
.sp-side { display: grid; grid-template-columns: repeat(3, 84px); gap: 8px; }
.sp-c1 { grid-column: 1; } .sp-c2 { grid-column: 2; } .sp-c3 { grid-column: 3; }
ts-spend-card:is([data-state="ended"], [data-state="cancelled"]) .sp-c2 { grid-column: 1; }
ts-spend-card:is([data-state="ended"], [data-state="cancelled"]) .sp-c3 { grid-column: 2; }
.sp-side .stat .l { min-height: 20px; }
.sp-side .stat.small-v .v { font-size: var(--t-20); }
.sp-meter { position: relative; height: 8px; border-radius: 4px; background: var(--page-deep); }
.sp-fill { position: absolute; inset: 0 auto 0 0; width: var(--w); border-radius: 4px; background: linear-gradient(90deg, var(--violet), var(--violet-ring));
  transition: width calc(var(--d-slow) * 1.5) var(--ease-out); }
.sp-exp { position: absolute; top: -4px; bottom: -4px; left: var(--at); width: 2px; border-radius: 1px; background: var(--ink); transition: left var(--d-slow) var(--ease-spring); }
ts-spend-card[data-state="ended"] .sp-fill, ts-spend-card[data-state="cancelled"] .sp-fill { background: var(--mint-deep); }
ts-spend-card .stat.key .v { font-size: var(--t-44); }
@media (max-width: 599px) { ts-spend-card { padding: 16px 16px 14px; } .sp-side { gap: 10px 16px; } }
/* Hero (the progress screen's page top, from 600 px): no card, as the planner's price; the key amount's glow is the page
   top's (page-top.css) */
@media (min-width: 600px) {
  ts-spend-card[data-layout="hero"] { align-content: center; gap: 12px; padding: 0; overflow: visible; background: none; border-radius: 0; box-shadow: none; }
  ts-spend-card[data-layout="hero"] .sp-key .l { font-size: var(--t-15); color: var(--ink-2); }
  ts-spend-card[data-layout="hero"] .sp-side { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
}
@media (min-width: 900px) { ts-spend-card[data-layout="hero"] .stat.key .v { font-size: var(--t-72); line-height: 1; letter-spacing: -0.025em; } }

/* ui/c/status-line.css */
/* Status line (ts-status-line): the session's one line of state at the bottom of the hero. The text is typed (see
   status-line.js); the box is reserved for two lines, and the message sits at its bottom, so nothing moves. */
ts-status-line { display: grid; grid-template-columns: 8px minmax(0, 1fr); align-items: end; gap: 9px; font-size: var(--t-13); line-height: 1.4; font-weight: 500; color: var(--ink-2); }
ts-status-line > .live-dot { margin-bottom: 5px; }
.sl-box { position: relative; display: grid; align-items: end; min-height: calc(2 * 1.4 * var(--t-13)); }
.sl-vis { display: block; min-width: 0; white-space: pre-wrap; }
.ch { opacity: 0; transition: opacity calc(60ms * var(--motion-scale)) linear; }
.ch.on { opacity: 1; }
.ll-dots { display: inline-block; margin-left: 1px; white-space: nowrap; opacity: 0; }
.ll-dots.on { opacity: 1; }
.ll-dots i { display: inline-block; width: 3px; height: 3px; margin-left: 2.5px; border-radius: 50%; background: currentColor; opacity: 0.7; }
@keyframes ll-wave { 0%, 55%, 100% { opacity: 0.3; translate: 0 0; } 25% { opacity: 1; translate: 0 -2px; } }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .ll-dots.on i { animation: ll-wave calc(1.5s * max(var(--motion-scale), 1)) ease-in-out infinite; }
  html:not([data-motion="reduce"]) .ll-dots.on i:nth-child(2) { animation-delay: 0.2s; }
  html:not([data-motion="reduce"]) .ll-dots.on i:nth-child(3) { animation-delay: 0.4s; }
}

/* ui/c/light-trail.css */
/* Light trail (ts-light-trail): the violet curve of light across the progress screen's photo (the page top's), behind
   the page's text. Mounted with state="live" or state="ended"; it fills the box it sits in (the photo's box from 600 px,
   the photo band above the title under it). data-lt (set by the element) is the look it draws: live, or ended (also
   under reduced motion). On a phone the band is --lt-band tall, and the curve keeps above the title where the title
   overlaps the band (--lt-floor). variant="hero" is a public page hero's wide ribbon (light-trail.js); it is placed the
   same way. */
ts-light-trail { position: absolute; inset: 0; z-index: -1; display: block; pointer-events: none; contain: strict; }
ts-light-trail canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* On a phone the trail lies over the photo band and fades out before the title */
@media (max-width: 599px) {
  ts-light-trail { bottom: auto; z-index: 0; height: var(--lt-band, 104px); --lt-floor: 38px;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--lt-floor) - 6px), transparent calc(100% - var(--lt-floor) + 6px));
    mask-image: linear-gradient(to bottom, #000 calc(100% - var(--lt-floor) - 6px), transparent calc(100% - var(--lt-floor) + 6px)); }
}

/* ui/c/live-panel.css */
/* Live panel */
ts-live-panel { display: grid; gap: 14px; align-content: start; padding: 18px 18px 20px; }
.lp-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 32px; }
.lp-film { position: relative; display: grid; place-items: center; align-content: center; gap: 14px; aspect-ratio: 16 / 9; border-radius: var(--r-ctl); overflow: hidden; background: var(--film); color: #fff; isolation: isolate; }
.lp-glow { position: absolute; inset: -20%; z-index: -1; background: radial-gradient(closest-side at 50% 55%, color-mix(in oklch, var(--violet) 45%, transparent), transparent 70%), radial-gradient(closest-side at 70% 30%, oklch(70% 0.1 160 / 0.25), transparent 70%); }
.lp-ring .ring { width: 72px; height: 72px; }
.lp-msg { display: grid; justify-items: center; gap: 10px; max-width: 32ch; text-align: center; font-size: var(--t-15); font-weight: 500; color: oklch(100% 0 0 / 0.9); padding: 0 16px; }
.lp-prog { display: block; width: 180px; height: 4px; border-radius: 2px; background: oklch(100% 0 0 / 0.2); overflow: hidden; }
.lp-prog i { display: block; width: var(--w); height: 100%; background: var(--mint); border-radius: 2px; transition: width var(--d-slow) var(--ease-out); }
.lp-play { position: relative; }
.lp-play .pl { border-radius: var(--r-ctl); aspect-ratio: 16 / 10; }
.lp-play .pl-big { display: none; }
.lp-cap { position: absolute; left: 10px; bottom: 10px; z-index: 4; display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 12px; border-radius: var(--r-ctl);
  background: oklch(18% 0.01 285 / 0.55); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); color: #fff; }
.lp-id { font-family: var(--font-heading); font-weight: 650; font-size: var(--t-17); }
.lp-cap .chip { background: oklch(100% 0 0 / 0.16); color: #fff; }
.lp-mini .ring { width: 26px; height: 26px; }
.lp-mini .rg-track { stroke-width: 5; }
.lp-mini .rg-arc, .lp-mini .rg-sweep { stroke-width: 5; }
.lp-first { grid-auto-flow: column; align-items: center; gap: 10px; }
.lp-first .chip { background: oklch(100% 0 0 / 0.16); color: #fff; }
/* From 1280 px the panel is the screen's right column, kept in view beside the plans, with a taller player (4:3, the clip's
   middle shown) */
@media (min-width: 1280px) { .lp-film, .lp-play .pl { aspect-ratio: 4 / 3; } }
/* 900-1279 px: the panel sits under the timeline's row at the page's width, so its player is 16:9 */
@media (min-width: 900px) and (max-width: 1279px) { .lp-play .pl { aspect-ratio: 16 / 9; } }

/* ui/c/clip-panel.css */
/* Clip panel */
ts-clip-panel { display: block; }
ts-clip-panel.card { padding: 14px 18px 20px; }
.cp-in, ts-clip-panel .sh-body { display: grid; gap: 14px; align-content: start; }
.cp-back { justify-self: start; margin-left: -8px; gap: 6px; }
.cp-back .i { width: 16px; height: 16px; }
.cp-t { display: flex; align-items: center; gap: 10px; }
.cp-id { font-size: var(--t-card-heading); }
.cp-ph { position: relative; aspect-ratio: 16 / 9; border-radius: var(--r-ctl); overflow: hidden; }
.cp-ph .cf-ph { border-radius: var(--r-ctl); }
.cp-ph .ring { width: 80px; height: 80px; }
.cp-act { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
.cp-dl { width: 100%; }
.cp-act ts-menu .mn-trig { box-shadow: inset 0 0 0 1px var(--hair-2); }
.cp-dl-list { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 9px 18px; padding-top: 14px; border-top: 1px solid var(--hair); font-size: var(--t-15); }
.cp-dl-list dt { color: var(--muted); }
.cp-dl-list dd { color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
.cp-prompt { line-height: 1.5; color: var(--ink-2); }
.cp-why { margin: 0; }

/* ui/c/bottom-bar.css */
/* Bottom bar: sticky on a desktop, the one full-width action fixed on a phone. The planner's Create floats on its own
   from 600 px, at the bottom right with no strip behind it (operator, 2026-10-30) */
ts-bottom-bar { display: block; position: sticky; bottom: 0; z-index: 25; padding: 10px 0 calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--page) 62%, color-mix(in oklch, var(--page) 0%, transparent)); }
.bb-in { display: flex; align-items: center; gap: 12px 20px; min-height: 72px; padding: 12px 12px 12px var(--pad-card); border-radius: var(--r-page); background: var(--surface); box-shadow: var(--shadow); }
.bb-info { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 20px; min-width: 0; flex: 1; }
.bb-count { font-family: var(--font-heading); font-weight: 650; font-size: var(--t-17); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.bb-line { font-size: var(--t-13); color: var(--muted); }
.bb-acts { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.bb-main { min-height: 48px; padding: 0 22px; }
.bb-create { min-height: 56px; padding: 0 34px; border-radius: var(--r-card); font-size: var(--t-17); }
/* The planner's Create: the word and the brand's spark; with nothing to make, opaque grey so nothing shows through */
ts-bottom-bar[data-mode="planner"] .bb-create { gap: 10px; }
.bb-spark { width: 18px; height: 18px; color: var(--violet-soft); }
ts-bottom-bar[data-mode="planner"] .bb-create[disabled] { opacity: 1; background: var(--page-deep); color: var(--faint); box-shadow: inset 0 0 0 1px var(--hair); }
ts-bottom-bar[data-mode="planner"] .bb-create[disabled] .bb-spark { color: var(--hair-2); }
ts-bottom-bar[data-mode="planner"] .bb-info:empty, ts-bottom-bar[data-mode="trim"] .bb-info:empty, ts-bottom-bar[data-mode="picks"] .bb-info:empty, ts-bottom-bar[data-mode="action"] .bb-info:empty { display: block; }
@media (min-width: 600px) {
  ts-bottom-bar[data-mode="planner"] { position: fixed; z-index: 25; left: auto; right: max(var(--gutter), calc((100vw - var(--content)) / 2 + var(--gutter))); bottom: calc(24px + env(safe-area-inset-bottom));
    padding: 0; background: none; pointer-events: none; }
  ts-bottom-bar[data-mode="planner"] .bb-in { display: block; min-height: 0; padding: 0; border-radius: 0; background: none; box-shadow: none; }
  ts-bottom-bar[data-mode="planner"] .bb-info { display: none; }
  ts-bottom-bar[data-mode="planner"] .bb-main { pointer-events: auto; border-radius: var(--r-pill); min-width: var(--create-w); min-height: 58px; padding: 0 40px 0 46px; }
  ts-bottom-bar[data-mode="planner"] .bb-spark { width: 22px; height: 22px; }
}
@media (max-width: 599px) {
  ts-bottom-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 8px var(--gutter) calc(10px + env(safe-area-inset-bottom)); }
  .bb-in { flex-wrap: wrap; align-content: flex-start; gap: 8px 10px; padding: 10px; border-radius: var(--r-page); min-height: 168px; }
  .bb-info { flex-basis: 100%; padding: 2px 6px 0; gap: 2px 12px; }
  .bb-info:empty { display: none; }
  .bb-acts { flex: 1; flex-wrap: wrap; overflow: visible; }
  .bb-acts > .btn:not(.bb-main):not(.icon) { flex: 1 1 100%; }
  .bb-main { flex: 1; min-height: 56px; border-radius: var(--r-card); font-size: var(--t-17); }
  .bb-create { padding: 0 20px; }
  /* The slot keeps the progress bar's height through its states; a bar with one action is only as tall as it */
  ts-bottom-bar:is([data-mode="planner"], [data-mode="picks"], [data-mode="trim"], [data-mode="compare"], [data-mode="action"]) .bb-in { min-height: 0; }
}

/* ui/c/money-ring.css */
/* Money ring */
ts-money-ring { display: grid; gap: 10px; container: mr / inline-size; }
.mr-wrap { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 18px; align-items: center; }
.mr { width: 96px; height: 96px; rotate: -90deg; }
.mr circle { fill: none; stroke-width: 24; }
.mr-bg { stroke: var(--page-deep); }
.mr-arc { transition: stroke-dasharray var(--d-slow) var(--ease-out), stroke-dashoffset var(--d-slow) var(--ease-out); }
.mr-lg { display: grid; gap: 8px; font-size: var(--t-13); color: var(--ink-2); }
.mr-lg li { display: grid; grid-template-columns: 9px minmax(0, 1fr) auto; gap: 8px; align-items: baseline; }
.mr-lg i { width: 9px; height: 9px; border-radius: 50%; background: var(--c); translate: 0 1px; }
.mr-pc { font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.mr-sh { font-weight: 500; color: var(--muted); }
.mr-total { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-top: 8px; border-top: 1px solid var(--hair); font-size: var(--t-13); font-weight: 600; color: var(--ink-2); }
.mr-tv { font-family: var(--font-figure); font-size: var(--t-17); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
/* a narrow card keeps each part on one line: a smaller ring, and under 280 px the dollars alone */
@container mr (max-width: 312px) { .mr-wrap { grid-template-columns: 72px minmax(0, 1fr); gap: 10px; } .mr { width: 72px; height: 72px; } }
@container mr (max-width: 279px) { .mr-sh { display: none; } }
/* 600-1099 px: the card spans the page; the legend stays beside the ring rather than spreading across it */
@media (min-width: 600px) and (max-width: 1099px) { .mr-wrap { max-width: 520px; } }

/* ui/c/savings.css */
/* Savings banner and modal: one surface colour, mint, for both (6.1: the modal is the banner's own colour) */
ts-savings { display: block; --sv-surface: linear-gradient(115deg, oklch(96.5% 0.04 160), oklch(97.5% 0.025 175) 55%, oklch(96.8% 0.03 150)); --sv-edge: color-mix(in oklch, var(--mint-deep) 22%, transparent); }
.sv-b { position: relative; isolation: isolate; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 14px; width: 100%; min-height: 64px;
  padding: 10px 14px 10px 14px; border-radius: 18px; text-align: left; color: var(--ink); }
.sv-bg { position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--sv-surface); box-shadow: inset 0 0 0 1px var(--sv-edge); transition: box-shadow var(--d-quick); }
@media (hover: hover) { .sv-b:hover .sv-bg { box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--mint-deep) 45%, transparent), 0 8px 22px -14px oklch(56% 0.11 160 / 0.45); } }
.sv-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--mint-deep); color: #fff; box-shadow: 0 6px 14px -6px oklch(56% 0.11 160 / 0.6); }
.sv-ic .i { width: 20px; height: 20px; }
.sv-lines { display: grid; min-width: 0; overflow: hidden; }
.sv-line { grid-area: 1 / 1; font-size: var(--t-15); line-height: 1.4; color: var(--ink-2); }
.sv-line b { font-weight: 600; color: var(--ink); }
.sv-line .v-saved { font-family: var(--font-figure); font-size: var(--t-17); color: var(--mint-ink); }
.sv-line.leaving { animation: sv-out var(--d-move) var(--ease-in) forwards; }
@keyframes sv-out { to { opacity: 0; translate: 0 -6px; } }
.sv-dots { display: inline-flex; gap: 5px; }
.sv-dots i { width: 6px; height: 6px; border-radius: 50%; background: color-mix(in oklch, var(--mint-deep) 28%, transparent); transition: background-color var(--d-move), width var(--d-move) var(--ease-out); }
.sv-dots i.on { width: 16px; border-radius: 3px; background: var(--mint-deep); }
.sv-go { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; color: var(--mint-ink); background: oklch(100% 0 0 / 0.6); }
.sv-go .i { width: 16px; height: 16px; }
/* Under 600 px the banner is a line of the screen's summary card */
@media (max-width: 599px) { .sv-b { grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; min-height: 52px; padding: 6px 10px; border-radius: var(--r-card); } .sv-dots { display: none; } .sv-line { font-size: var(--t-13); } .sv-line .v-saved { font-size: var(--t-15); }
  .sv-ic { width: 32px; height: 32px; border-radius: 9px; } .sv-go { width: 32px; height: 32px; } }

/* The modal: the banner's surface, grown */
.sv-m { width: min(560px, calc(100vw - 24px)); max-height: calc(100dvh - 32px); padding: 0; border: 0; border-radius: 24px; background: transparent; color: var(--ink); overflow: visible;
  transition: opacity var(--d-fade) var(--ease-out), scale var(--d-move) var(--ease-spring), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.sv-m:not([open]) { opacity: 0; scale: 0.97; }
@starting-style { .sv-m[open] { opacity: 0; scale: 0.97; } }
.sv-m.vt { transition: none; }
.sv-m::backdrop { background: oklch(22% 0.02 285 / 0.3); transition: opacity var(--d-fade), display var(--d-move) allow-discrete, overlay var(--d-move) allow-discrete; }
.sv-m:not([open])::backdrop { opacity: 0; }
@starting-style { .sv-m[open]::backdrop { opacity: 0; } }
.sv-m-in { display: grid; gap: 14px; padding: 20px 22px 22px; border-radius: 24px; background: var(--sv-surface); box-shadow: inset 0 0 0 1px var(--sv-edge), 0 30px 80px -24px oklch(30% 0.06 160 / 0.45); }
.sv-m-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sv-m-h .t-title { font-size: var(--t-card-heading); }
.sv-t { width: 100%; border-collapse: collapse; font-size: var(--t-15); }
.sv-t th, .sv-t td { padding: 11px 0; text-align: left; border-bottom: 1px solid color-mix(in oklch, var(--mint-deep) 16%, transparent); }
.sv-t thead th { padding-top: 0; font-size: var(--t-13); font-weight: 600; color: var(--muted); }
.sv-t tbody th { font-weight: 650; }
.sv-t .n { text-align: right; font-variant-numeric: tabular-nums lining-nums; }
.sv-t td.n + td.n, .sv-t th.n + th.n { padding-left: 18px; }
/* each row's saving is the hero: one mint pill led by the share saved, the amount beside it; the API price is a plain secondary figure */
.fig-s { font-family: var(--font-figure); font-weight: 600; font-size: var(--t-15); color: var(--ink-2); }
.sv-t .sv-c { width: 54%; text-align: right; }
.sv-pill { display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 8px; padding: 4px 14px 5px; border-radius: 999px; background: color-mix(in oklch, var(--mint) 55%, transparent); color: var(--mint-ink); white-space: nowrap; }
.sv-pct { font-family: var(--font-figure); font-weight: 650; font-size: 26px; line-height: 1.15; letter-spacing: -0.01em; color: var(--mint-ink); font-variant-numeric: tabular-nums lining-nums; }
.sv-save { font-family: var(--font-figure); font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums lining-nums; }
.sv-dot::before { content: ""; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: currentColor; vertical-align: middle; opacity: 0.6; }
/* each provider's own mark before its name */
.sv-prov { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
.sv-logo { flex: none; width: 24px; height: 24px; border-radius: 6px; }
.sv-basis { font-size: var(--t-13); color: var(--ink-2); }
::view-transition-group(savings) { animation-duration: calc(420ms * var(--motion-scale)); animation-timing-function: var(--ease-spring); }
::view-transition-old(savings), ::view-transition-new(savings) { animation-duration: calc(260ms * var(--motion-scale)); height: 100%; object-fit: none; overflow: clip; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: calc(240ms * var(--motion-scale)); }

/* ui/c/price-card.css */
/* Price card: hero (on the page: the key amount over the Cap) and sheet (Expected and Cap side by side); the same nodes in both */
ts-price-card { position: relative; display: grid; align-content: space-between; gap: 10px; min-width: 0; padding: 14px var(--pad-card) 14px; isolation: isolate; overflow: hidden;
  background: var(--surface); border-radius: var(--r-page); box-shadow: var(--shadow); }
.pc .stat .l { gap: 2px; }
ts-price-card .pc-exp .v { font-size: var(--t-72); line-height: 1; letter-spacing: -0.025em; }
.pc-exp .v::before { right: -110px; }
.pc-tiles { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); padding-top: 10px; border-top: 1px solid var(--hair); }
.pc-tiles > .stat + .stat { padding-left: 16px; border-left: 1px solid var(--hair); }
.pc-tiles .stat .v { font-size: var(--t-22); line-height: 1.1; }
/* The plans count is a count, so the sans; check.py holds it on the Cap figure's ink centre (ruling 7) */
.pc-n { font-family: var(--font-heading); font-weight: 650; letter-spacing: -0.01em; }

ts-price-card[data-layout="sheet"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-content: start; padding: 12px 18px 14px; border-radius: var(--r-card); box-shadow: var(--shadow-sm); }
ts-price-card[data-layout="sheet"] .pc-tiles { display: contents; }
ts-price-card[data-layout="sheet"] .pc-plans { display: none; }
ts-price-card[data-layout="sheet"] .pc-cap { padding-left: 18px; border-left: 1px solid var(--hair); }
ts-price-card[data-layout="sheet"] .pc-exp .v, ts-price-card[data-layout="sheet"] .pc-cap .v { font-size: var(--t-44); line-height: 1.05; letter-spacing: -0.02em; }
ts-price-card[data-layout="sheet"] .pc-exp .v::before { width: 160px; height: 160px; right: -70px; }

/* The hero from 900 px: Expected at 72 px (plan 3.2), over the key stat's 56 */
@media (min-width: 900px) { ts-price-card[data-layout="hero"] .pc-exp.stat.key .v { font-size: var(--t-72); } }
/* The hero from 600 px: no card; Expected large with the glow, the Cap as one line under it */
@media (min-width: 600px) {
  ts-price-card[data-layout="hero"] { align-content: center; gap: 8px; padding: 0; overflow: visible; background: none; border-radius: 0; box-shadow: none; }
  ts-price-card[data-layout="hero"] .pc-tiles { display: block; padding-top: 0; border-top: 0; }
  ts-price-card[data-layout="hero"] .pc-plans { display: none; }
  ts-price-card[data-layout="hero"] .pc-tiles > .pc-cap { display: flex; align-items: center; gap: 8px; padding-left: 0; border-left: 0; }
  ts-price-card[data-layout="hero"] .pc-cap .l, ts-price-card[data-layout="hero"] .pc-exp .l { font-size: var(--t-15); color: var(--ink-2); }
  /* the mint glow is the page top's (page-top.css) */
  ts-price-card[data-layout="hero"] .pc-cap .v { font-size: var(--t-22); }
}
@media (max-width: 599px) {
  ts-price-card[data-layout="hero"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-content: start; }
  ts-price-card[data-layout="hero"] .pc-tiles { display: contents; }
  ts-price-card[data-layout="hero"] .pc-plans { display: none; }
  ts-price-card[data-layout="hero"] .pc-cap { padding-left: 16px; border-left: 1px solid var(--hair); }
  ts-price-card .pc-exp .v, ts-price-card .pc-cap .v, ts-price-card[data-layout="sheet"] .pc-exp .v, ts-price-card[data-layout="sheet"] .pc-cap .v { font-size: var(--t-34); }
  ts-price-card .pc-exp .v::before { width: 150px; height: 150px; right: -60px; }
}

/* ui/c/scene-diagram.css */
/* Scene diagram: one row of columns that scrolls sideways as one (the shared descriptions, then each shot's takes),
   joined by pills and purple branch curves at the row's middle; one column of numbered shot cards on a phone */
ts-scene-diagram { display: grid; gap: var(--gap); min-width: 0; --take-w: 168px; }
.sd-scroll { margin: 0 calc(-1 * var(--pad-card)); padding: 12px var(--pad-card) 14px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-padding-inline: var(--pad-card); scrollbar-width: thin; scroll-snap-type: none; }
.sd-flow { position: relative; display: flex; align-items: stretch; width: max-content; }
.sd-links { position: absolute; left: 0; top: 0; z-index: 0; overflow: visible; pointer-events: none; }
.sd-path { fill: none; stroke: var(--branch); stroke-width: 1.6; stroke-opacity: 0.85; stroke-linecap: round; transition: stroke-opacity var(--d-quick) var(--ease-out); }
.sd-path.hot { stroke-opacity: 1; stroke-width: 2.25; }
.sd-arrow { fill: var(--branch); }
/* the row fades at an edge it can scroll past (fl, fr: draw() and the scroll keep them); 56 px hides a cut pill (FADE in scene-diagram.js) */
.sd-scroll.fl { -webkit-mask-image: linear-gradient(to right, transparent, #000 56px); mask-image: linear-gradient(to right, transparent, #000 56px); }
.sd-scroll.fr { -webkit-mask-image: linear-gradient(to left, transparent, #000 56px); mask-image: linear-gradient(to left, transparent, #000 56px); }
.sd-scroll.fl.fr { -webkit-mask-image: linear-gradient(to right, transparent, #000 56px, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to right, transparent, #000 56px, #000 calc(100% - 56px), transparent); }
.sd-gap { flex: 0 0 56px; }
/* from 600 px the row ends with room for the floating Create, so the last shot and the Add a shot tile scroll clear of it */
@media (min-width: 600px) { .sd-scroll { padding-right: calc(var(--pad-card) + var(--create-w)); } }
/* a note under a lane or a pill hangs below the row: the row grows to hold it, and gives the room back below, so nothing moves */
@media (min-width: 600px) { .sd-scroll:has(ts-note) { padding-bottom: 60px; margin-bottom: -46px; } }
/* A column: its number and title, its takes and its "+", from the row's top */
.sd-lane { position: relative; z-index: 1; flex: 0 0 var(--take-w); display: flex; flex-direction: column; justify-content: flex-start; gap: 8px; width: var(--take-w); min-width: 0; }
.sd-lane.base { flex-basis: 232px; width: 232px; }
/* holdTop() measures the lanes with every prompt closed */
ts-scene-diagram.sd-measure ts-take-card .tk-prompt:not(.tk-none) { -webkit-line-clamp: 3; line-clamp: 3; max-height: 3lh; transition: none; }
/* a lane that carries a note rises over the next lane and its join, so the note is whole */
.sd-lane:has(> ts-note) { z-index: 3; }
/* a shot with several takes holds them as compact horizontal cards, so it is a little wider */
.sd-lane.multi { flex-basis: 216px; width: 216px; }
/* the selected take's lane widens (--sel-w, set by the component) so its whole prompt reads in a wider column; the lanes
   beside it move aside */
@media (min-width: 600px) {
  .sd-lane[data-shot] { transition: flex-basis var(--d-move) var(--ease-out), width var(--d-move) var(--ease-out); }
  .sd-lane[data-shot].on { flex-basis: var(--sel-w, 420px); width: var(--sel-w, 420px); }
  .sd-lane.multi[data-shot].on { flex-basis: var(--sel-wc, 500px); width: var(--sel-wc, 500px); }
}
/* endState() reads the row as it will be: nothing moves while it does */
ts-scene-diagram.sd-freeze .sd-lane, ts-scene-diagram.sd-freeze ts-take-card .tk-prompt { transition: none !important; }
/* a lane title wraps to two lines; its box keeps two lines of height so every lane's cards start at the same level */
.sd-lh { display: flex; align-items: flex-start; gap: 8px; min-width: 0; min-height: 40px; font-size: var(--t-13); line-height: 1.4; }
.sd-n { flex: none; display: inline-grid; place-items: center; min-width: 24px; height: 24px; padding: 0 6px; border-radius: 7px; background: var(--violet-soft); color: var(--violet-ink);
  font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums lining-nums; transition: background-color var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.sd-lane.on .sd-n { background: var(--violet); color: #fff; }
.sd-lt { min-width: 0; padding-top: 3px; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-weight: 600; color: var(--ink-2); }
.sd-lane.base .sd-lt { color: var(--muted); }
.sd-body { display: flex; flex-direction: column; justify-content: flex-start; gap: var(--gap); min-width: 0; overflow: visible; }
.sd-body > ts-take-card { width: 100%; }
/* The join after a lane: the pill sits on the curves between two shots (draw() sets its top to their midpoint) */
/* narrow, so the pill sits over the two cards' edges, as in the concept */
.sd-join { position: relative; z-index: 2; flex: 0 0 40px; align-self: stretch; }
.sd-join[data-join="continuous"] { flex-basis: 96px; }
.sd-join.end { flex-basis: 40px; }
/* beside a shot with several takes the join widens, so the fan into and out of the pill has room to read */
.sd-lane.multi + .sd-join, .sd-join:has(+ .sd-lane.multi) { flex-basis: 112px; }
.sd-lane.multi + .sd-join[data-join="continuous"], .sd-join[data-join="continuous"]:has(+ .sd-lane.multi) { flex-basis: 144px; }
/* into a shot of several takes the gutter holds its pill (or a pill per take, each level with its take) toward its
   right, with room for the curve on into the take, and the point the shot's takes meet at its left; the same width
   split or not, so nothing beside it moves */
.sd-flow > .sd-join.per:has(+ .sd-lane.multi) { flex-basis: 216px; }
.sd-pin { position: absolute; left: 50%; top: var(--y, 50%); translate: -50% -50%; }
.sd-join.per .sd-pin { left: auto; right: 40px; translate: 0 -50%; }
@media (min-width: 600px) { .sd-pill-id { display: none; } }
.sd-pill-b { display: grid; place-items: center; min-width: 44px; min-height: 44px; border-radius: var(--r-pill); }
.sd-pill { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: var(--r-pill);
  background: var(--surface); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--branch) 40%, var(--hair-2)), 0 2px 6px -3px color-mix(in oklch, var(--violet-ink) 25%, transparent);
  font-size: 12px; font-weight: 600; color: var(--violet-ink); white-space: nowrap; transition: box-shadow var(--d-quick) var(--ease-out), background-color var(--d-quick) var(--ease-out); }
@media (hover: hover) { .sd-pill-b:not([aria-disabled="true"]):hover .sd-pill { background: var(--violet-soft); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--branch) 70%, transparent), 0 2px 6px -3px color-mix(in oklch, var(--violet-ink) 30%, transparent); } }
.sd-pill-b:focus-visible { outline: none; }
.sd-pill-b:focus-visible .sd-pill { outline: 2px solid var(--violet); outline-offset: 2px; }
/* A locked join (its shot's takes all made): the dimmed track of the locked Starts from switch, its label kept, with
   no hover */
.sd-pill-b[aria-disabled="true"] { cursor: default; }
.sd-pill-b[aria-disabled="true"] .sd-pill.locked { background: var(--page-deep); box-shadow: inset 0 1px 2px oklch(25% 0.02 285 / 0.08);
  color: color-mix(in oklch, var(--violet-ink) 65%, var(--faint)); }
/* the pills per take leaving as the one pill comes back */
.sd-pin.sd-ghost { pointer-events: none; }
.sd-pill-id { margin-right: 5px; font-weight: 650; }
/* The add points: a quiet round "+" in a 44 px target. Under a join pill it shows on hover or focus (always on a touch
   screen), on a short line from the pill; under a shot's takes and after the last shot it always shows */
.sd-plus { position: relative; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: var(--violet); isolation: isolate; }
.sd-plus::before { content: ""; position: absolute; z-index: -1; inset: 8px; border-radius: 50%; background: var(--surface);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 35%, var(--hair-2)), 0 2px 6px -3px color-mix(in oklch, var(--violet-ink) 25%, transparent);
  transition: background-color var(--d-quick) var(--ease-out), box-shadow var(--d-quick) var(--ease-out), scale var(--d-quick) var(--ease-spring); }
.sd-plus .i { width: 14px; height: 14px; stroke-width: 2.2; }
@media (hover: hover) { .sd-plus:hover::before { background: var(--violet-soft); box-shadow: inset 0 0 0 1.5px var(--violet); scale: 1.08; } }
.sd-plus:focus-visible { outline: none; }
.sd-plus:focus-visible::before { box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 3px var(--violet-soft); }
.sd-ins { position: absolute; left: 50%; top: calc(100% + 10px); translate: -50% 0; opacity: 0; scale: 0.85; pointer-events: none;
  transition: opacity var(--d-quick) var(--ease-out), scale var(--d-quick) var(--ease-spring); }
.sd-ins::after { content: ""; position: absolute; left: 50%; bottom: calc(100% - 8px); width: 1.5px; height: 12px; translate: -50% 0; background: color-mix(in oklch, var(--branch) 45%, transparent); }
.sd-join:hover .sd-ins, .sd-join:has(:focus-visible) .sd-ins { opacity: 1; scale: 1; pointer-events: auto; }
@media (hover: none) { .sd-ins { opacity: 1; scale: 1; pointer-events: auto; } }
.sd-addt { align-self: center; margin-top: -4px; }
/* A folded shot: "+N more takes" under its first three, a quiet pill that opens the rest (Show fewer folds them) */
.sd-more { align-self: center; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px; border-radius: 999px; font-size: var(--t-13); font-weight: 600; color: var(--violet-ink); }
.sd-more::before { content: ""; position: absolute; inset: 7px 0; z-index: -1; border-radius: inherit; background: var(--violet-soft); }
.sd-more { position: relative; isolation: isolate; }
.sd-more-i { width: 14px; height: 14px; transition: rotate var(--d-quick) var(--ease-out); }
.sd-more[aria-expanded="true"] .sd-more-i { rotate: 180deg; }
.sd-more:focus-visible { outline: 2px solid var(--violet); outline-offset: -5px; }
/* the add-a-take "+" shows while the pointer is over the row (not the editor box below it) or the keyboard's focus is inside the row (a
   focus a click left there does not count); its slot stays */
@media (hover: hover) {
  .sd-addt { opacity: 0; visibility: hidden; }
  .sd-scroll:hover .sd-addt, .sd-scroll:has(:focus-visible) .sd-addt { opacity: 1; visibility: visible; }
  /* the pointer left the row by a scroll, not a move (recheckHover) */
  ts-scene-diagram[data-off-row] .sd-scroll:not(:has(:focus-visible)) .sd-addt { opacity: 0; visibility: hidden; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html:not([data-motion="reduce"]) .sd-addt { transition: opacity 120ms var(--ease-out), visibility 120ms var(--ease-out); }
}
/* Add a shot: a dashed tile at the take card's size at the end of the row (the add concept) */
.sd-endw { flex: 0 0 var(--take-w); display: flex; flex-direction: column; justify-content: center; translate: 0 -8px; }
.sd-end { display: grid; place-items: center; align-content: center; gap: 10px; height: 210px; border-radius: var(--r-card); outline: 1.5px dashed var(--hair-2); outline-offset: -1.5px;
  color: var(--ink-2); font-size: var(--t-15); font-weight: 600; transition: background-color var(--d-quick) var(--ease-out), outline-color var(--d-quick) var(--ease-out); }
.sd-end .i { width: 26px; height: 26px; stroke-width: 1.6; }
@media (hover: hover) { .sd-end:hover { background: color-mix(in oklch, var(--violet-soft) 40%, transparent); outline-color: var(--violet); } }
.sd-end:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
/* a description's first reference picture, 16:9 beside its text */
.sd-desc-pic { display: block; flex: none; width: 96px; aspect-ratio: 16 / 9; border-radius: var(--r-poster); overflow: hidden; background: var(--page-deep); }
.sd-desc-pic img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
/* A shared description: the take card's frame and tick, its text in two lines */
.sd-desc { padding-bottom: 10px; }
.sd-desc .cf-h { gap: 10px; }
.sd-desc .cf-id { font-size: var(--t-15); }
.sd-desc .cf-t { color: var(--ink-2); }
.sd-desc.off .cf-id, .sd-desc.off .cf-t { opacity: 0.45; }
.sd-desc.on { box-shadow: 0 0 0 2px var(--violet), var(--shadow-sm); }
/* Its text opens the shared descriptions editor */
.sd-desc-open { display: flex; align-items: flex-start; gap: 10px; width: 100%; min-height: 44px; margin: -4px 0 0; padding: 4px 0 0; text-align: left; border-radius: var(--r-ctl); }
.sd-desc-open .cf-t { flex: 1; min-width: 0; }
.sd-desc-open .cf-t { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sd-desc-open .cf-t.empty { color: var(--muted); font-style: italic; }
@media (hover: hover) { .sd-desc-open:hover .cf-t { color: var(--violet-ink); } }
.sd-desc-open:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
/* The editors under the row */
ts-scene-diagram > ts-shot-editor, ts-scene-diagram > ts-desc-editor { margin-top: 2px; }

@media (max-width: 599px) {
  ts-scene-diagram { --take-w: auto; }
  .sd-scroll { overflow: visible; margin: 0; padding: 0; }
  .sd-flow { display: grid; grid-template-columns: minmax(0, 1fr); width: auto; }
  .sd-links, .sd-gap { display: none; }
  .sd-lane, .sd-lane.base, .sd-lane.multi { width: auto; justify-content: flex-start; gap: 10px; padding: 12px 0 14px; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); }
  .sd-lane.base { margin-bottom: var(--gap); }
  .sd-lh { padding: 0 14px; min-height: 32px; font-size: var(--t-15); white-space: normal; }
  .sd-n { min-width: 28px; height: 28px; border-radius: 8px; font-size: var(--t-13); }
  .sd-lt { display: block; padding-top: 0; overflow: visible; }
  .sd-body { flex-direction: row; justify-content: flex-start; align-items: flex-start; padding: 4px 14px 4px; scroll-padding-inline: 14px; overflow-x: auto; }
  .sd-body > ts-take-card { flex: 0 0 100%; }
  .sd-lane.multi .sd-body > ts-take-card { flex-basis: 84%; transition: flex-basis var(--d-move) var(--ease-out); }
  /* the selected take takes the row's visible width */
  .sd-lane.multi .sd-body > ts-take-card.sel { flex-basis: 100%; }
  .sd-lane.base .sd-body { display: flex; flex-direction: column; overflow: visible; padding-right: 14px; }
  .sd-join, .sd-join[data-join="continuous"], .sd-join.end { display: grid; place-items: center; height: 44px; }
  .sd-join::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; translate: -1px 0; background: color-mix(in oklch, var(--branch) 45%, transparent); }
  .sd-pin, .sd-join.per .sd-pin { position: relative; left: auto; right: auto; top: auto; translate: none; }
  /* the pills per take sit in a row between the two cards, each named by its take */
  .sd-join.per { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0 4px; height: auto; min-height: 44px; }
  /* while a shot's takes differ the line stops at the pill row's top and bottom edges (the pills are 24 px in their 44 px buttons), so it never runs behind a pill */
  .sd-join.per[data-join="mixed"]::before { --ln: color-mix(in oklch, var(--branch) 45%, transparent); background: linear-gradient(to bottom, var(--ln) 10px, transparent 10px calc(100% - 10px), var(--ln) calc(100% - 10px)); }
  .sd-ins { left: calc(100% + 2px); top: 50%; translate: 0 -50%; }
  .sd-ins::after { display: none; }
  .sd-join.end { height: 20px; }
  .sd-endw { translate: none; }
  .sd-end { height: 64px; grid-auto-flow: column; justify-content: center; }
  .sd-addt { margin: -2px 0 -6px; }
}

/* ui/c/shot-editor.css */
/* Shot editor: the head; the side column (title, shot defaults, characters, lengths, shot actions); the prompts */
ts-shot-editor { display: grid; gap: 16px; min-width: 0; container: se / inline-size; }
ts-shot-editor[data-layout="dock"] { padding: 14px 18px 18px; border-radius: var(--r-card); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair); }
.se-h { display: flex; align-items: center; gap: 10px; min-width: 0; }
.se-title { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.se-st { font-family: var(--sans); font-size: var(--t-15); font-weight: 500; color: var(--ink-2); }
.se-nav { flex: none; display: inline-flex; gap: 2px; }
.se-x { margin: -8px -8px -8px 0; }
.se-shead { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: -8px; }
.se-sub { min-width: 0; font-weight: 600; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.se-side, .se-main { display: grid; gap: 16px; align-content: start; min-width: 0; }
.se-main { gap: 8px; }
.se-gl { font-size: var(--t-13); font-weight: 600; color: var(--muted); }
.se-hint { font-size: 12.5px; color: var(--muted); }
.se-titlef .se-title-in { min-height: 44px; padding: 9px 12px; }
ts-shot-editor.locked .se-title-in, ts-shot-editor.locked .se-text { color: var(--ink-2); }

/* The shot defaults: frames, then references, each a tile; the tiles wrap to the column's width */
.se-defs { display: grid; gap: 8px; min-width: 0; }
.se-defs-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.se-strip { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 14px 12px; padding-top: 4px; }
.se-grp { flex: 0 1 auto; display: grid; gap: 6px; min-width: 0; }
.se-grl { font-size: 11.5px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.se-trow { display: flex; flex-wrap: wrap; gap: 14px 12px; }
.se-sep { display: none; }
.se-tile { position: relative; flex: 0 0 118px; width: 118px; min-width: 0; }
.se-tpic { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 9px; overflow: hidden; background: var(--page-deep); box-shadow: var(--shadow-sm); cursor: zoom-in; }
.se-tpic img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
.se-tpic.add { display: grid; place-items: center; background: none; box-shadow: none; outline: 1.5px dashed var(--hair-2); outline-offset: -1.5px; color: var(--muted); cursor: pointer;
  transition: outline-color var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.se-tpic.add .i { width: 18px; height: 18px; }
@media (hover: hover) { .se-tpic.add:hover { outline-color: var(--violet); color: var(--violet); } }
.se-tpic.cont { display: grid; place-items: center; cursor: default; background: linear-gradient(160deg, var(--wash), var(--violet-soft)); color: var(--violet); }
.se-tpic.cont img { position: absolute; inset: 0; opacity: 0.45; filter: saturate(0); }
.se-tpic.cont .i { position: relative; width: 24px; height: 24px; }
.se-tpic.off img { opacity: 0.45; filter: saturate(0); }
.se-tile.story .se-tpic img { outline: 1px dashed color-mix(in oklch, var(--ink) 30%, transparent); outline-offset: -3px; filter: saturate(0.6); }
/* A tile's menu: a 44 px target over its corner, drawn as a small round button */
.se-tile > ts-menu { position: absolute; top: -12px; right: -12px; }
.se-tile > ts-menu .mn-trig { isolation: isolate; border-radius: 50%; background: none; }
.se-tile > ts-menu .mn-trig::before { content: ""; position: absolute; z-index: -1; inset: 6px; border-radius: 50%; background: color-mix(in oklch, var(--surface) 92%, transparent); box-shadow: var(--shadow-sm); }
.se-tile > ts-menu .mn-trig[aria-expanded="true"] { background: none; }
.se-tile > ts-menu .mn-trig[aria-expanded="true"]::before { background: var(--violet-soft); }
.se-tcap { margin-top: 5px; font-size: 12px; line-height: 1.35; color: var(--muted); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.se-tcap b { color: var(--ink); font-weight: 600; }
.se-tsub::before { content: " · "; }
.se-tnote { margin-top: 2px; font-size: 11.5px; line-height: 1.3; color: var(--violet-ink); }
.se-cont-note { font-size: var(--t-13); color: var(--violet-ink); }

/* Add the characters: a switch with its line */

/* The lengths: each a chip inside a 44 px target with its ×; one at a time turns into a field */
.se-lens-g { display: grid; gap: 4px; }
.se-lens { display: flex; flex-wrap: wrap; align-items: center; gap: 0 2px; margin: -4px 0 -4px -8px; }
.se-len { height: 28px; }
.se-lenc { display: inline-flex; align-items: center; }
.se-lenb { display: inline-grid; place-items: center; min-width: 44px; min-height: 44px; padding: 0 2px 0 4px; border-radius: var(--r-ctl); }
.se-lenx { display: grid; place-items: center; width: 44px; min-height: 44px; margin: 0 -8px 0 -12px; border-radius: var(--r-ctl); color: var(--muted); }
.se-lenx .i { width: 13px; height: 13px; }
@media (hover: hover) {
  .se-lenb:hover .se-len { box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--violet) 45%, transparent); color: var(--violet-ink); }
  .se-lenx:hover { color: var(--bad); }
}
.se-lens > .chip { margin: 8px 4px; }
.se-lenf { position: relative; display: inline-flex; align-items: center; gap: 4px; height: 44px; padding: 0 4px; }
.se-len-in { width: 52px; height: 44px; padding: 0 8px; border: 0; border-radius: 9px; background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--violet), 0 0 0 4px var(--violet-soft);
  font-size: var(--t-15); font-weight: 600; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
.se-len-in:focus { outline: none; }
.se-len-u { font-size: var(--t-13); font-weight: 600; color: var(--ink-2); }
.se-len-r { margin-left: 4px; white-space: nowrap; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Add length and Add prompt: quiet text buttons with a plus */
.se-add { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 10px; border-radius: var(--r-ctl); font-size: var(--t-13); font-weight: 600; color: var(--violet-ink); }
.se-add .i { width: 15px; height: 15px; }
@media (hover: hover) { .se-add:hover { background: var(--violet-soft); } }
.se-addp { justify-self: start; margin: -2px 0 -8px -4px; }
.se-shot-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Remove this shot, refused: the button faint, the reason beside it */
.se-rm-shot { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.se-rm-shot .btn { opacity: 0.45; cursor: default; }
.se-why { font-size: var(--t-13); color: var(--muted); }

/* A prompt: a card; closed, two lines and a small picture of what it starts from; open, the switch, its text, its frames */
.se-prompts { display: grid; gap: 8px; }
.se-pr { display: grid; gap: 8px; padding: 0 14px 12px; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); }
.se-pr-h { display: flex; flex-wrap: wrap; align-items: center; gap: 0 4px; margin: 0 -14px; }
.se-pr-t { flex: 1 1 220px; min-width: 0; display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 8px 0 14px; border-radius: var(--r-card) var(--r-card) 0 0; text-align: left; }
.se-pn { font-weight: 650; color: var(--ink); white-space: nowrap; }
.se-pl { font-size: var(--t-13); color: var(--muted); }
.se-sp { flex: 1; }
.se-chev { width: 16px; height: 16px; color: var(--muted); transition: rotate var(--d-quick) var(--ease-out); }
.se-pr-t[aria-expanded="true"] .se-chev { rotate: 180deg; }
.se-pr-acts { flex: none; display: inline-flex; gap: 2px; margin-left: auto; padding-right: 6px; }
.btn.se-danger { color: var(--bad); }
.se-mode { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.se-mode.frames { background: var(--violet-soft); color: var(--violet-ink); }
.se-mode.references { background: var(--mint-soft); color: var(--mint-ink); }
.se-mode.text { background: var(--page-deep); color: var(--ink-2); }
.se-mode.off { opacity: 0.55; }
.se-peek { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 16px; margin-top: -6px; text-align: left; border-radius: var(--r-ctl); }
.se-peek-t { font-size: var(--t-13); line-height: 1.45; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.se-peek-t.none { color: var(--bad); font-weight: 550; }
.se-mini { display: flex; align-items: center; gap: 4px; }
.se-mini .sf-th { width: 64px; }
.se-link { width: 14px; height: 1.5px; background: var(--hair-2); }
.se-more { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.se-body { display: grid; gap: 12px; }
.se-tw { display: grid; }
.se-text { width: 100%; min-height: 5lh; padding: 10px 12px; border: 0; border-radius: var(--r-ctl); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-15); line-height: 1.5; color: var(--ink); resize: vertical; field-sizing: content; }
.se-text:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet); }
/* A prompt's takes: each a tick with its length and id, and × when it is not the shot's last */
.se-takes { display: flex; flex-wrap: wrap; gap: 6px; }
.se-tk { display: inline-flex; }
.se-tk.rm .se-take { border-radius: var(--r-ctl) 0 0 var(--r-ctl); padding-right: 10px; }
.se-rm { display: grid; place-items: center; width: 44px; min-height: 44px; border-radius: 0 var(--r-ctl) var(--r-ctl) 0; box-shadow: inset 0 0 0 1px var(--hair-2); margin-left: -1px; color: var(--muted); }
.se-rm .i { width: 14px; height: 14px; }
@media (hover: hover) { .se-rm:hover { color: var(--bad); background: var(--bad-soft); } }
.se-take { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px 0 10px; border-radius: var(--r-ctl); background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-13); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums; }
.se-take .tk-box { width: 20px; height: 20px; border-radius: 6px; }
.se-take .tk-box .i { width: 13px; height: 13px; }
.se-take[aria-checked="false"] .tk-box { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair-2); }
.se-take[aria-checked="false"] .tk-box .i { opacity: 0; scale: 0.6; }
.se-take[aria-checked="true"] { box-shadow: inset 0 0 0 1.5px color-mix(in oklch, var(--violet) 45%, transparent); color: var(--ink); }
.se-tid { color: var(--muted); font-weight: 600; }
.se-tl { color: inherit; }
@media (hover: hover) { .se-pr:not(.open) .se-pr-t:hover .se-pn, .se-peek:hover .se-peek-t { color: var(--violet-ink); } }

/* The dock from 900 px: the side column beside the prompts */
@media (min-width: 900px) {
  ts-shot-editor[data-layout="dock"] { grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); column-gap: 24px; align-items: start; }
  ts-shot-editor[data-layout="dock"] .se-h { grid-column: 1 / -1; }
}
/* A narrow editor: a closed prompt's text over its pictures */
@container se (max-width: 520px) { .se-peek { grid-template-columns: minmax(0, 1fr); gap: 8px; } }

/* ui/c/plan-strip.css */
/* Plan settings strip: one joined, rounded group of cells split by 1 px hairlines, each with a small label over its value.
   Each cell is as wide as its label or its value, whichever is wider (88 px at least); the strip is as wide as its cells */
ts-plan-strip { display: block; min-width: 0; }
.ps { display: grid; grid-auto-flow: column; grid-auto-columns: auto; gap: 1px; width: max-content; max-width: 100%; border-radius: 14px; overflow: hidden; background: var(--hair-2); box-shadow: 0 0 0 1px var(--hair-2); }
.ps-c { position: relative; display: grid; min-width: 88px; min-height: 56px; background: var(--surface); transition: background-color var(--d-quick) var(--ease-out); }
/* the label and the control share the cell's one grid area, the label over the control's top padding */
.ps-c > * { grid-area: 1 / 1; }
@media (hover: hover) { .ps-c:hover { background: var(--wash); } }
.ps-c:has(.mn-trig[aria-expanded="true"]) { background: var(--wash); }
.ps-l { position: relative; z-index: 1; align-self: start; margin: 9px 14px 0; white-space: nowrap; pointer-events: none; font-size: 11.5px; line-height: 1.2; color: var(--muted); }
.ps-c ts-menu { display: block; min-width: 0; }
.ps-c .mn-cell { position: relative; display: flex; align-items: center; width: 100%; min-height: 56px; margin: 0; padding: 25px 32px 7px 14px; border: 0; border-radius: 0; background: transparent; color: var(--ink);
  font: 600 15px/1.3 var(--serif); font-variant-numeric: tabular-nums lining-nums; text-align: left; cursor: pointer; }
.ps-c .mn-cell:focus-visible, .ps-c .ps-in:focus-visible { outline: 2px solid var(--violet); outline-offset: -3px; border-radius: 14px; }
.ps-c .mn-val { display: flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; white-space: nowrap; }
.ps-c .mn-val > b { font-weight: inherit; overflow: hidden; text-overflow: ellipsis; }
.ps-c .mn-val > small { font: 400 13px var(--sans); color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.ps-c .mn-chev { position: absolute; right: 11px; top: 50%; width: 14px; height: 14px; margin-top: -7px; color: var(--faint); pointer-events: none; transition: rotate var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.ps-c .mn-cell[aria-expanded="true"] .mn-chev { rotate: 180deg; color: var(--ink-2); }
.ps-c.model .mn-cell { font-size: 17px; }
/* the seed's field holds six digits */
.ps-in { display: block; width: calc(6ch + 28px); min-width: 100%; min-height: 56px; margin: 0; padding: 25px 14px 7px; border: 0; border-radius: 0; background: transparent; color: var(--ink); cursor: text;
  font: 600 15px/1.3 var(--serif); font-variant-numeric: tabular-nums lining-nums; }
/* A comparison's seeds: one tick chip each, and Add a seed */
.ps-c.seeds { padding: 26px 12px 8px 14px; }
.ps-c.seeds > .ps-l { margin: -17px 0 0; }
.ps-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ps-chips .cg-dim { min-height: 44px; }
@media (max-width: 760px) {
  .ps { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; }
  .ps-c { min-width: 0; }
  .ps-l { overflow: hidden; text-overflow: ellipsis; }
  .ps-in { width: 100%; }
  .ps-c.model, .ps-c.seeds { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) { .ps-c, .ps-c .mn-chev { transition: none; } }

/* ui/c/compare-grid.css */
/* Comparison grid: the progress group's prompt rows (plan-group.css .pgp-prow, .pgp-pcard), with take cards */
ts-compare-grid { display: block; min-width: 0; --card-w: 264px; }
@media (max-width: 599px) { ts-compare-grid { --card-w: calc(100vw - 2 * var(--gutter) - 48px); } }
.cg.pgp-cmp { padding: 4px 0 0; }
ts-compare-grid .pgp-prow { margin: 0 calc(-1 * var(--pad-card)); padding-top: 12px; padding-bottom: 8px; }
/* from 600 px the takes grow to share the card's width (up to 360 px each), so a small grid fills it */
.cg-cell { flex: 0 0 var(--card-w); display: grid; gap: 8px; align-content: start; }
.cg-cell > ts-take-card { width: 100%; }
/* The prompt card is the row's one statement of its prompt (its takes leave it out), sized by its text */
ts-compare-grid .pgp-pcard { align-self: start; }
.cg-use { justify-self: start; }
.cg-use[aria-pressed="true"] { background: var(--violet-soft); color: var(--violet-ink); box-shadow: inset 0 0 0 1.5px var(--violet); }
.cg-none { flex: none; align-self: center; }
.cg-none .btn[aria-pressed="true"] { background: var(--page-deep); color: var(--ink); }
@media (max-width: 599px) {
  ts-compare-grid .pgp-prow { margin: 0; }
  ts-compare-grid .pgp-pcard { margin-inline: 0; }
  ts-compare-grid .pgp-trow { padding-inline: 0; margin-inline: 0; }
}
/* The planner: the plan's models, lengths and seeds, each a tick; a prompt card's tick, and its text opening to a field */
.cg-dims { display: grid; gap: 10px; padding: 4px 0 8px; }
.cg-grp { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; }
.cg-gl { flex: 0 0 64px; font-size: var(--t-13); font-weight: 600; color: var(--muted); }
.cg-ticks { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.cg-dim { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px 0 10px; border-radius: var(--r-ctl); background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-13); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums; }
.cg-dim .tk-box { width: 20px; height: 20px; border-radius: 6px; }
.cg-dim .tk-box .i { width: 13px; height: 13px; }
.cg-dim[aria-checked="false"] { color: var(--muted); }
.cg-dim[aria-checked="false"] .tk-box { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair-2); }
.cg-dim[aria-checked="false"] .tk-box .i { opacity: 0; scale: 0.6; }
.cg-dim[aria-checked="true"] { box-shadow: inset 0 0 0 1.5px color-mix(in oklch, var(--violet) 45%, transparent); color: var(--ink); }
.cg-lin { width: 150px; height: 44px; padding: 0 12px; border: 0; border-radius: var(--r-ctl); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2); font-size: var(--t-13); color: var(--ink); }
.cg-lin:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet); }
.cg-help { display: grid; gap: 2px; font-size: 12.5px; color: var(--muted); }
.cg-pc .cf-h { gap: 10px; }
.cg-pc.off .cf-id, .cg-pc.off .cg-prompt { opacity: 0.45; }
.cg-pc.open { box-shadow: 0 0 0 2px var(--violet), var(--shadow-sm); }
.cg-rm { margin-left: auto; margin-right: -8px; }
.cg-open { display: block; width: 100%; min-height: 44px; text-align: left; border-radius: var(--r-ctl); }
.cg-prompt.empty { color: var(--muted); font-style: italic; }
@media (hover: hover) { .cg-open:hover .cg-prompt { color: var(--violet-ink); } }
.cg-open:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.cg-ta { width: 100%; padding: 8px 10px; border: 0; border-radius: var(--r-ctl); background: var(--wash); box-shadow: inset 0 0 0 1px var(--hair-2);
  font-size: var(--t-13); line-height: 1.45; color: var(--ink); resize: vertical; field-sizing: content; min-height: 5lh; }
.cg-ta:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--violet); }
/* An open prompt's reference images: the editor box's tiles (start-from.css), each with its number and a Remove × on
   its top right corner, a 24 px chip in a 44 px button */
.cg-refs { display: grid; gap: 8px; margin-top: 12px; }
.cg-refs .sf-refs { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
.cg-rt { position: relative; }
.cg-rrm { position: absolute; top: -6px; right: -6px; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: var(--ink-2); }
.cg-rx { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--surface); box-shadow: 0 1px 3px oklch(25% 0.02 285 / 0.25);
  transition: background-color var(--d-quick) var(--ease-out), color var(--d-quick) var(--ease-out); }
.cg-rx .i { width: 13px; height: 13px; stroke-width: 2.4; }
@media (hover: hover) { .cg-rrm:hover .cg-rx { color: var(--bad); background: var(--bad-soft); } }
.cg-rrm:focus-visible { outline: none; }
.cg-rrm:focus-visible .cg-rx { outline: 2px solid var(--violet); outline-offset: 2px; }
.cg-add { justify-self: start; margin: 4px 0 0 -4px; }
@media (max-width: 599px) { .cg-gl { flex-basis: 100%; } }
@media (max-width: 599px) { ts-compare-grid .pgp-prow.plan .cg-cell { flex-basis: 200px; } }
.cg-skip { color: var(--warn-ink); font-weight: 550; }
@media (min-width: 600px) { ts-compare-grid .pgp-prow > .pgp-trow > .cg-cell, ts-compare-grid .pgp-trow > .cg-cell { flex: 1 0 var(--card-w); max-width: 360px; } }
/* the planner's grid: the prompt card, then the takes as 200 px cells that wrap; a model with no take leaves no cell */
@media (min-width: 600px) {
  ts-compare-grid .pgp-prow.plan { flex-wrap: wrap; align-items: stretch; overflow: visible; }
  ts-compare-grid .pgp-prow.plan > .pgp-pcard { align-self: stretch; }
  ts-compare-grid .pgp-prow.plan > .pgp-trow > span { display: none; }
  ts-compare-grid .pgp-prow.plan > .pgp-trow > .cg-cell { flex: 0 0 200px; max-width: none; }
}
/* A take whose model leaves the prompt's reference images out says so under its tile, on one line, so the tile keeps its neighbours' height;
   the cell keeps a line of room under it */
.cg-cell:has(.tk-note) { margin-bottom: 24px; }
.cg-cell ts-take-card.tile > .cf-f:has(.tk-note) { position: absolute; top: 100%; left: 0; min-height: 0; padding: 4px 2px 0; }
.cg-cell .tk-note { white-space: nowrap; }

/* ui/c/confirm.css */
/* Confirm: the plan list and the session's line and timeline (.cn-a), then the price, the after-hold figure and Run (.cn-b) */
ts-confirm { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; min-width: 0; }
.cn-a, .cn-b { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; min-width: 0; align-content: start; }
.cn-agent { display: flex; align-items: center; gap: 8px; font-size: var(--t-13); font-weight: 600; color: var(--violet-ink); }
.cn-agent .live-dot { background: var(--violet); }
.cn-plans { display: grid; gap: 2px; }
.cn-cols { display: flex; align-items: center; min-height: 20px; padding-right: 0; font-size: var(--t-13); font-weight: 500; color: var(--muted); }
.cn-col { text-align: right; }
.cn-list { display: grid; }
.cn-row { min-height: 52px; display: grid; grid-template-columns: minmax(0, 1fr); align-items: center; border-top: 1px solid var(--hair); }
/* In the sheet the kind gives way, so the plan's name keeps its room; the page shows it */
ts-confirm[data-layout="sheet"] .cn-row .chip.kind { display: none; }
.cn-row:last-child { border-bottom: 1px solid var(--hair); }
.cn-row .pgp-name { font-size: var(--t-15); }
.cn-row.off .pgp-mark, .cn-row.off .pgp-name, .cn-row.off .chip { opacity: 0.45; }
.cn-row .tk-tick { flex: none; }
.cn-tickpad { flex: none; width: 24px; }
/* A plan whose frames do not all match its aspect: the line under its row (the frame-shape badge's "!") */
.cn-mis { display: flex; align-items: center; gap: 6px; margin: -6px 0 10px; padding-left: calc(var(--pad-card, 20px) + 44px); font-size: var(--t-13); font-weight: 600; color: var(--warn-ink); }
.cn-mis::before { content: "!"; display: grid; place-items: center; flex: none; width: 16px; height: 16px; border-radius: 50%; background: var(--warn-ink); color: #fff; font-size: 11px; font-weight: 800; line-height: 1; }
.cn-setup { min-width: 0; font-size: var(--t-13); font-weight: 500; color: var(--ink-2); }
.cn-clips { font-size: var(--t-13); color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums; }
/* Credits after the hold: the mint card */
.cn-after { position: relative; isolation: isolate; display: grid; gap: 2px; padding: 14px 18px 16px; border-radius: var(--r-card); background: var(--mint-soft);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--mint-deep) 18%, transparent); overflow: hidden; }
.cn-after::before { content: ""; position: absolute; z-index: -1; width: 180px; height: 180px; right: -50px; top: -70px; border-radius: 50%; background: var(--glow-mint); pointer-events: none; }
.cn-after .l { font-size: var(--t-13); font-weight: 600; color: var(--mint-ink); }
.cn-after .v { font-family: var(--font-figure); font-optical-sizing: auto; font-weight: 600; font-size: var(--t-34); line-height: 1.05; letter-spacing: -0.015em; color: var(--mint-ink); font-variant-numeric: tabular-nums lining-nums; }
.cn-go { display: grid; gap: 4px; }
.cn-run { margin-top: 4px; }
/* A refusal and a price change share one slot of fixed height, so Run and Keep editing never move */
.cn-slot { display: grid; align-items: center; min-height: calc(2 * 1.4 * var(--t-13)); }
.cn-note { font-size: var(--t-13); line-height: 1.4; color: var(--muted); text-align: center; }
.cn-note.bad { color: var(--bad); font-weight: 550; }
.cn-note.up { color: var(--warn-ink); font-weight: 600; }
/* Run's amount: a figure the money tween can count */
.cn-run .v-usd { position: relative; display: inline-block; font-weight: inherit; font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.cn-run .v-usd.tweening { -webkit-text-fill-color: transparent; }
/* A refresh raised the cap: the figures it changed keep a soft amber wash while the line says so */
ts-confirm.raised ts-price-card .mt-fig, ts-confirm.raised .cn-after .v, ts-confirm.raised [data-figure="setup-expected"] .fig-n {
  border-radius: 8px; background: var(--warn-soft); box-shadow: 0 0 0 5px var(--warn-soft); transition: background-color var(--d-move) var(--ease-out), box-shadow var(--d-move) var(--ease-out); }
ts-confirm.raised .cn-after .v, ts-confirm.raised ts-price-card .mt-fig { justify-self: start; width: fit-content; }
ts-confirm.raised .cn-run .v-usd { color: oklch(87% 0.12 90); }
.cn-back { justify-self: center; }

/* The page: two columns of cards from 900 px */
ts-confirm[data-layout="page"] .cn-a, ts-confirm[data-layout="page"] .cn-b { padding: var(--pad-card); border-radius: var(--r-page); background: var(--surface); box-shadow: var(--shadow); }
ts-confirm[data-layout="page"] .cn-back { justify-self: center; }
@media (min-width: 900px) {
  ts-confirm[data-layout="page"] { grid-template-columns: minmax(0, 1fr) minmax(340px, 400px); gap: var(--gap); align-items: start; }
}
@media (max-width: 599px) {
  .cn-after .v { font-size: var(--t-28); }
  /* Run is the fixed action at the foot of the sheet or the page (6.0) */
  .sh-body ts-confirm[data-layout="sheet"] .cn-go { position: sticky; bottom: 0; z-index: 2; margin: 0 -20px -24px; padding: 10px 20px calc(10px + env(safe-area-inset-bottom)); background: var(--surface); box-shadow: 0 -1px 0 var(--hair); }
  ts-confirm[data-layout="page"] .cn-go { position: fixed; left: 0; right: 0; bottom: 0; z-index: 25; padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom)); background: var(--surface); box-shadow: 0 -1px 0 var(--hair), 0 -12px 30px -18px oklch(25% 0.03 285 / 0.25); }
  ts-confirm[data-layout="page"] .cn-b { padding-bottom: var(--pad-card); }
}
@media (max-width: 599px) {
  /* A phone's row keeps the plan's name whole: the clips count is in the session's line under the list */
  ts-confirm .cn-row .chip.count, ts-confirm .cn-row .chip.kind { display: none; }
  .cn-row.setup .pgp-name { white-space: normal; overflow: visible; line-height: 1.3; }
  /* The start-up label wraps here: its figures sit on its first line, on the same ink centre (ruling 7) */
  .cn-row.setup .pgp-h { align-items: first baseline; }
  .cn-row.setup .pgp-mark { align-self: flex-start; margin-top: calc((1.3em - 12px) / 2); font-size: var(--t-15); }
}

/* ui/c/session-row.css */
/* Session row: a grid row on a desktop, a card on a phone; it opens in place (M10) */
ts-session-row { position: relative; display: block; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); transition: box-shadow var(--d-quick); }
@media (hover: hover) { ts-session-row:hover { box-shadow: 0 0 0 1px color-mix(in oklch, var(--violet) 25%, transparent), var(--shadow-sm); } }
.sr-tg { position: absolute; inset: 0 0 auto 0; height: 76px; z-index: 1; border-radius: var(--r-card) var(--r-card) 0 0; }
.sr-row { display: grid; grid-template-columns: 88px minmax(0, 1.6fr) minmax(120px, 0.7fr) minmax(130px, 0.6fr) minmax(90px, 0.45fr) 24px; align-items: center; gap: 16px; min-height: 76px; padding: 10px 16px 10px 10px; }
.sr-pic { width: 88px; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 10px; background: var(--page-deep); }
.sr-name { display: grid; gap: 3px; min-width: 0; }
.sr-title { display: flex; align-items: center; gap: 8px; min-width: 0; font-weight: 600; }
.sr-title > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-date { font-size: var(--t-13); color: var(--muted); font-variant-numeric: tabular-nums; }
.sr-clips { display: grid; gap: 6px; }
.sr-n { font-weight: 600; font-variant-numeric: tabular-nums lining-nums; }
.sr-bar { display: block; height: 4px; border-radius: 2px; background: var(--page-deep); overflow: hidden; }
.sr-bar i { display: block; width: var(--w); height: 100%; border-radius: 2px; background: var(--mint-deep); }
ts-session-row:has(.chip.running) .sr-bar i { background: var(--violet); }
.sr-cost { display: grid; justify-items: end; gap: 0; text-align: right; }
.sr-cost .fig { font-size: var(--t-17); }
.sr-cl { font-size: var(--t-13); color: var(--muted); }
.sr-chev { color: var(--muted); }
.sr-chev .i { width: 18px; height: 18px; transition: rotate var(--d-move) var(--ease-out); }
ts-session-row.open .sr-chev .i { rotate: 180deg; }
.sr-x { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--d-move) var(--ease-out); }
@supports (interpolate-size: allow-keywords) { .sr-x { interpolate-size: allow-keywords; } }
.sr-x.open { grid-template-rows: 1fr; }
.sr-x-in { min-height: 0; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(220px, 1fr); gap: 16px 32px; padding: 0 16px; }
.sr-x.open .sr-x-in { padding: 6px 16px 18px; border-top: 1px solid var(--hair); }
.sr-tl { padding-top: 12px; }
.sr-money { padding-top: 8px; }
@media (max-width: 899px) {
  .sr-row { grid-template-columns: 72px minmax(0, 1fr) auto; grid-template-areas: "pic name cost" "pic clips clips" "pic st st"; gap: 6px 12px; padding: 10px 12px 10px 10px; }
  .sr-pic { grid-area: pic; width: 72px; align-self: start; }
  .sr-name { grid-area: name; } .sr-clips { grid-area: clips; } .sr-st { grid-area: st; justify-self: start; } .sr-cost { grid-area: cost; } .sr-chev { display: none; }
  .sr-tg { height: 100%; max-height: 96px; }
  .sr-x-in { grid-template-columns: minmax(0, 1fr); }
  .sr-title { flex-wrap: wrap; white-space: normal; }
  .sr-title > span:first-child { white-space: normal; }
}

/* ui/c/credit-row.css */
/* Credit activity row; it shares the session row's opening panel (.sr-x) */
ts-credit-row { position: relative; display: block; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); }
.crw-tg { position: absolute; inset: 0 0 auto 0; height: 64px; z-index: 1; border-radius: var(--r-card) var(--r-card) 0 0; }
.crw-row { display: grid; grid-template-columns: 64px minmax(0, 1fr) minmax(90px, auto) minmax(110px, auto) 44px; align-items: center; gap: 14px; min-height: 64px; padding: 8px 10px 8px 18px; }
.crw-date { font-size: var(--t-13); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.crw-what { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.crw-t { font-weight: 600; min-width: 0; }
.crw-amt, .crw-after { display: grid; justify-items: end; text-align: right; }
.crw-amt .fig { font-size: var(--t-17); }
.crw-amt .fig.plus { color: var(--mint-ink); }
.crw-after .fig { font-size: var(--t-15); color: var(--ink-2); }
.crw-l { font-size: 12px; color: var(--muted); }
.crw-chev { display: grid; place-items: center; color: var(--muted); }
.crw-chev .i { width: 18px; height: 18px; transition: rotate var(--d-move) var(--ease-out); }
ts-credit-row.open .crw-chev .i { rotate: 180deg; }
.crw-rc { position: relative; z-index: 2; color: var(--ink-2); }
@media (max-width: 699px) {
  .crw-row { grid-template-columns: minmax(0, 1fr) auto 44px; grid-template-areas: "what amt end" "date after end"; gap: 2px 12px; padding: 10px 6px 10px 14px; }
  .crw-what { grid-area: what; } .crw-amt { grid-area: amt; } .crw-date { grid-area: date; } .crw-after { grid-area: after; }
  .crw-row > :last-child { grid-area: end; }
  .crw-after { grid-auto-flow: column; gap: 6px; align-items: baseline; }
  .crw-tg { height: 100%; max-height: 80px; }
}
