/* Darkroom UI kit tokens ("Graphite"). Every colour, font, size, radius, spacing and shadow the kit uses lives here
   and nowhere else: ui/kit/*.js and ui/kit/*.css (except this file) may only say var(--dr-...).
   tests/ui/uit_tokens.py enforces it.

   Dark only for now. A light look later is one more block of the same names (e.g. :root[data-theme=light]).
   Contrast (rule R2, tests/ui/rules.py): every text token is >= 4.5:1 on every surface below, --dr-seg-on and the
   on look included; --dr-text-ter is the faintest (APCA Lc 61 on the panel; --dr-text-dis is only for what can't be used).
   Kit foundations 2026-10-20 (Justin's picks from the kit review): 5 text tiers, 6 type sizes each with its line height,
   a focus ring of its own, a strong field edge, z and easing scales. Old names are aliases at the end of :root until
   every branch has moved (python scripts/kit_tokens_migrate.py; the map: plan/research/kit-foundations/token-map.md). */

/* Geist / Geist Mono are the design's fonts but aren't on this computer (ui/kit/QUESTIONS.md): Inter and
   JetBrains Mono, already bundled for the old shell, stand in until Geist files are added under ui/kit/fonts. */
@font-face { font-family:"Inter Variable"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url(/shell/fonts/inter-latin-wght-normal.woff2) format("woff2"); }
@font-face { font-family:"JetBrains Mono Variable"; font-style:normal; font-weight:100 800; font-display:swap;
  src:url(/shell/fonts/jetbrains-mono-latin-wght-normal.woff2) format("woff2"); }

:root {
  /* ---- surfaces: six roles, darkest to lightest, each step 1.06-1.11:1 (Radix's 12-step roles: 1-2 app and subtle
     backgrounds, 3-5 a control at rest / hovered / pressed or selected). Kit foundations 2026-10-20: was 17 steps,
     six of them 1.01-1.04:1 apart ---- */
  /* the page, the bars, behind an image */
  --dr-ground:#0c0d0f;
  /* a column, a card, a list */
  --dr-panel:#131418;
  /* over a panel: popovers, menus, a lifted card */
  --dr-raised:#1a1b20;
  /* a control at rest: a field, a chip */
  --dr-control:#212329;
  /* under the pointer */
  --dr-hover:#292b33;
  /* picked (the accent's tint) */
  --dr-selected:#2c3040;
  --dr-seg-on:#2c2f3a;
  --dr-thumb-empty:var(--dr-control);
  --dr-skeleton:var(--dr-raised);
  --dr-skeleton-2:#202228;
  /* the band of light sweeping across the skeletons (a few % lighter than them) */
  --dr-skeleton-shine:#ffffff0d;

  /* ---- hairlines ---- */
  /* scrollbars (thumb at rest, under the pointer, dragged) */
  --dr-scroll:#ffffff24;
  --dr-scroll-hover:#ffffff45;
  --dr-scroll-active:#ffffff66;
  /* three lines: a separator (1.22:1 on the panel), a card's or chip's edge (1.44:1), a field's (--dr-line-strong, 3.1:1) */
  --dr-line:#24262c;
  --dr-line-bold:#30323a;
  /* the edge of a field and a checkbox (3.1:1 on the panel: WCAG 1.4.11's 3:1 for a control's boundary); nothing else */
  --dr-line-strong:#60646f;
  --dr-line-strong-hover:#7a7e89;
  /* a ticked checkbox's mark (on the accent) */
  --dr-check:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2l2.3 2.3 4.7-5' fill='none' stroke='%230d0e10' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --dr-line-acc:#3b4170;
  --dr-line-acc-2:#4a518c;

  /* ---- text: five tiers ---- */
  /* names under the pointer / pressed */
  --dr-text-strong:#ffffff;
  /* primary: names, values */
  --dr-text:#ececef;
  /* secondary: body lines, icons */
  --dr-text-sec:#c4c6ce;
  /* tertiary: labels, meta, counts (APCA Lc 61 on the panel: readable at 11-12 px). Something off but still read (a
     step switched off, a hidden layer) is tertiary with an "off" chip, never disabled */
  --dr-text-ter:#b1b4bc;
  /* disabled: only for what can't be used */
  --dr-text-dis:#6c6f78;

  /* ---- the one accent: selected / active ---- */
  /* the logo's three colours (assets/brand/darkroom-logo.svg): only the logo uses them */
  --dr-logo-disc:#000000;
  --dr-logo-moon:#f59a3c;
  --dr-logo-ring:#ffffff;
  --dr-acc:#8b9cff;
  --dr-on-acc:#0d0e10;
  --dr-acc-text:#a9b5ff;
  --dr-acc-text-hover:#ccd3ff;
  --dr-acc-soft:#8b9cff24;
  --dr-acc-wash:#8b9cff14;
  /* focus is light, selection stays blue (focus != selection): a 2 px ring 2 px off the control */
  --dr-focus:#ffffff;
  --dr-focus-ring:2px solid var(--dr-focus);
  --dr-focus-gap:2px;
  /* a text field's focus (QA 2026-10-25, BB #14): its own edge turns light, one edge and no ring around it (QA
     2026-10-21); 1 px after a click or tap, 2 px by keyboard (the second pixel: --dr-field-focus-more, off after a
     pointer below), so a keyboard user still finds it */
  --dr-field-focus:#ffffff;
  --dr-field-focus-more:0 0 0 1px var(--dr-field-focus);
  /* the ONE "on" look (UI rule R7): every toggle / pressed state (a pressed dr-button, Compare on, the tool in use, a
     picked chip): an accent-tinted fill with an accent outline, clearly not the solid primary button. Green is "done" */
  --dr-on-bg:#262b45;
  --dr-on-bg-hover:#2e3456;
  --dr-on-line:#8b9cff;
  --dr-on-text:#ccd3ff;

  /* ---- GPU cost: Run / Render / Train only ---- */
  --dr-gpu:#f2994a;
  /* the "rendering" swirl (cards, list thumbnails, the steps viewer, maybe Render buttons): soft blobs over a dark base */
  --dr-mesh-base:#1b1512;
  --dr-mesh-1:#f2994ad9;
  --dr-mesh-2:#e47ab0a6;
  --dr-mesh-3:#7b8cff99;
  --dr-mesh-4:#c9a24a8c;
  --dr-mesh-line:#ffffff0f;
  --dr-mesh-turn:16s;
  --dr-on-gpu:#1b0f03;
  --dr-gpu-soft:#f2994a99;
  --dr-gpu-wash:#f2994a22;

  /* ---- states ---- */
  --dr-ok:#5fd08f;
  --dr-ok-text:#8fe0ad;
  --dr-ok-bg:#13251a;
  /* a command that just did something (Undo, Redo): a short green flash */
  --dr-ok-flash:#1f4a35;
  --dr-warn:#f2c879;
  --dr-warn-bg:#2a2410;
  --dr-warn-line:#6e5718;
  --dr-bad:#f0605a;
  --dr-bad-text:#f3a29e;
  --dr-bad-bg:#2a1615;
  --dr-bad-line:#6b2b28;

  /* ---- see-through layers ---- */
  --dr-scrim:#0d0e10d9;
  --dr-backdrop:#05060799;
  --dr-glass:#16171bf7;
  --dr-on-acc-line:#0d0e1044;
  --dr-on-acc-dim:#0d0e10aa;
  --dr-on-gpu-line:#1b0f0344;
  --dr-on-gpu-dim:#1b0f03aa;

  /* ---- area / swatch colours (areas, people, rider kinds): data colours, picked by index ---- */
  --dr-swatch-1:#7b8cff;
  --dr-swatch-2:#e47ab0;
  --dr-swatch-3:#3fbf9a;
  --dr-swatch-4:#f2994a;
  --dr-swatch-5:#6b6e78;
  --dr-swatch-6:#5d6170;
  --dr-swatch-7:#c9a24a;
  --dr-swatch-8:#5aa9e6;
  /* the colour picker's field: pure white and black (the colour maths' ends) and the handles' dark ring */
  --dr-pick-light:#ffffff;
  --dr-pick-dark:#000000;
  --dr-pick-ring:#00000073;
  /* the Cutout editor's backgrounds to judge an edge on (board C1's On: Black, White, Checker) and its Edge view's
     strip (the pixels the edge pass works out) */
  --dr-cut-black:#000000;
  --dr-cut-white:#ffffff;
  /* a video viewer's screen (the video editor's source and program viewers): letterbox around the frame */
  --dr-screen:#000000;
  --dr-cut-check-a:#9a9da6;
  --dr-cut-check-b:#6b6e78;
  --dr-cut-strip:#f2c94c;
  --dr-cut-hole:#f2c94c;

  /* ---- type ---- */
  --dr-font:"Geist","Inter Variable","Segoe UI Variable Text","Segoe UI",system-ui,sans-serif;
  --dr-mono:"Geist Mono","JetBrains Mono Variable","Cascadia Mono",Consolas,ui-monospace,monospace;
  /* six sizes, each with its line height (4 px grid): a rule that sets --dr-fs-x sets --dr-lh-x with it */
  --dr-fs-xs:11px;
  --dr-lh-xs:16px;
  --dr-fs-s:12px;
  --dr-lh-s:16px;
  --dr-fs:13px;
  --dr-lh-base:18px;
  --dr-fs-l:14px;
  --dr-lh-l:20px;
  --dr-fs-xl:16px;
  --dr-lh-xl:22px;
  /* a page's title (the phone's top line) */
  --dr-fs-h1:18px;
  --dr-lh-h1:24px;
  /* the inherited ratio: 13 / 18 */
  --dr-lh:1.3846;
  --dr-fw:400;
  --dr-fw-m:500;
  --dr-fw-b:600;
  --dr-caps-track:.04em;

  /* ---- sizes ---- */
  --dr-bar-h:40px;
  --dr-status-h:28px;
  --dr-ctl:30px;
  --dr-ctl-s:26px;
  --dr-ctl-l:38px;
  --dr-row:30px;
  --dr-row-l:32px;
  --dr-chip-h:22px;
  --dr-chip-hit:24px;
  /* icon boxes: 12 / 14 / 16 / 18 / 20 (a square icon, a dot's button) */
  --dr-icon-xs:12px;
  --dr-icon-s:14px;
  --dr-icon:16px;
  --dr-icon-l:18px;
  --dr-icon-xl:20px;
  --dr-target:24px;
  --dr-target-touch:44px;
  /* the phone's controls: how big they look (their finger target stays --dr-target-touch, by a ::before hit area) */
  --dr-touch-vis:36px;
  /* the phone's fields (text, number, pickers, tags, search, prompt): as tall as the finger target */
  --dr-field-touch:44px;
  /* the phone's bottom sheets that leave the image in view above them: the most one opens to (one that fits its content:
     a tool's settings, the Steps sheet, a step's sheet, a menu) or its height (the lists: History, Versions, + Step);
     30 % of the image stays in view (board SH2, Justin 2026-10-29: the half sheet was "nearly useless") */
  --dr-phone-sheet-h:70dvh;
  --dr-chip-touch:28px;
  --dr-swatch:8px;
  --dr-dot:7px;
  --dr-bar-thin:3px;
  --dr-bar-track:4px;

  /* ---- radius ---- */
  /* six radii (4 / 6 / 8 / 12 / 16 / round; was nine): small marks, chips and buttons, fields and cards, panels and
     popovers, sheets and frames */
  --dr-r-xs:4px;
  --dr-r-chip:6px;
  --dr-r-m:8px;
  --dr-r-xl:12px;
  --dr-r-xxl:16px;
  --dr-r-round:999px;

  /* ---- spacing (4 / 8 grid) ---- */
  --dr-sp-0:2px;
  --dr-sp-1:4px;
  /* the half steps the kit's rows, chips and buttons use (rule R6: no raw px for spacing) */
  --dr-sp-1h:6px;
  --dr-sp-2:8px;
  --dr-sp-2h:10px;
  --dr-sp-3:12px;
  --dr-sp-4:16px;
  --dr-sp-5:20px;
  --dr-sp-6:24px;
  --dr-sp-8:32px;
  --dr-sp-10:40px;
  /* an empty list's or grid's message, away from the edges */
  --dr-sp-12:48px;
  /* a row's text past its icon column (a step card's lines under its name, a field's text past its search icon) */
  --dr-indent:36px;
  --dr-gutter:16px;

  /* ---- shadows ---- */
  --dr-shadow-card:0 0 0 1px var(--dr-acc);
  --dr-shadow-pop:0 12px 34px #00000099;
  --dr-shadow-dock:0 10px 30px #00000077;
  --dr-shadow-dialog:0 30px 80px #000000cc;
  --dr-shadow-tab:inset 0 -2px 0 var(--dr-acc);


  /* ---- motion: every transition and animation takes its time from here (rule M1, Justin 2026-10-17: snappy; press
     feedback shows at once and is gone in about 150 ms: dr-button flashDone) ---- */
  --dr-fast:.12s;
  /* the loading spinner: Justin's eclipse (assets/brand/darkroom-spinner.svg, take K), one turn in --dr-spin; kept the
     same as the file by tests/test_spinner.py (python tests/test_spinner.py --write writes it again) */
  --dr-spin:2.2s;
  /* the brand mark's own colours (the logo, the lock screen's moon and padlock: kit/lock-mark.js) */
  --dr-mark-sun:#f59a3c;
  --dr-mark-ground:#000;
  --dr-mark-ring:#fff;
  /* the mark at rest (assets/brand/darkroom-logo.svg): the lock screen's, never moving like the spinner */
  --dr-mark:url("data:image/svg+xml,%3Csvg viewBox=%220 0 1418 1418%22 xmlns=%22http://www.w3.org/2000/svg%22 fill-rule=%22evenodd%22%3E%3Cg transform=%22matrix(1,0,0,1,-1045.275591,-1136.66641)%22%3E%3Cg%3E%3Ccircle cx=%221753.937%22 cy=%221846.216%22 r=%22595.744%22 fill=%22%23000%22/%3E%3Cg transform=%22matrix(0.965926,0.258819,-0.258819,0.965926,537.36994,-391.074281)%22%3E%3Cpath d=%22M2198.068,2006.665C2132.077,2188.068 1958.034,2317.769 1753.937,2317.769C1493.19,2317.769 1281.496,2106.075 1281.496,1845.328C1281.496,1641.231 1411.196,1467.188 1592.6,1401.196C1554.503,1466.591 1532.673,1542.605 1532.673,1623.679C1532.673,1868.129 1731.136,2066.592 1975.586,2066.592C2056.659,2066.592 2132.674,2044.762 2198.068,2006.665Z%22 fill=%22%23f59a3c%22/%3E%3C/g%3E%3Cpath d=%22M1753.937,1136.666C2145.058,1136.666 2462.598,1454.207 2462.598,1845.328C2462.598,2236.449 2145.058,2553.989 1753.937,2553.989C1362.816,2553.989 1045.276,2236.449 1045.276,1845.328C1045.276,1454.207 1362.816,1136.666 1753.937,1136.666ZM1753.937,1284.304C1444.3,1284.304 1192.913,1535.69 1192.913,1845.328C1192.913,2154.965 1444.3,2406.351 1753.937,2406.351C2063.574,2406.351 2314.961,2154.965 2314.961,1845.328C2314.961,1535.69 2063.574,1284.304 1753.937,1284.304Z%22 fill=%22%23fff%22/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  --dr-spinner:url("data:image/svg+xml,%3Csvg viewBox=%221045.275591 1136.66641 1418 1418%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cdefs%3E%3CclipPath id=%22dr-eclipse%22%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22480%22/%3E%3C/clipPath%3E%3C/defs%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22595.744%22 fill=%22%23000%22/%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22472.441%22 fill=%22%23f59a3c%22/%3E%3Cg clip-path=%22url(%23dr-eclipse)%22%3E%3Cg%3E%3CanimateTransform attributeName=%22transform%22 type=%22rotate%22 values=%220.00 1439.67 987.54%3B-60.42 1439.67 987.54%3B-299.58 1439.67 987.54%3B-360.00 1439.67 987.54%22 keyTimes=%220.0000%3B0.4600%3B0.5400%3B1.0000%22 calcMode=%22spline%22 keySplines=%220.6 0 0.9 0.5%3B0 0 1 1%3B0.1 0.5 0.4 1%22 dur=%222.2s%22 repeatCount=%22indefinite%22/%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22442.913%22 fill=%22%23000%22%3E%3Canimate attributeName=%22r%22 values=%22480.4%3B442.9%3B442.9%3B480.4%22 keyTimes=%220.0000%3B0.3219%3B0.6781%3B1.0000%22 dur=%222.2s%22 repeatCount=%22indefinite%22/%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3Cpath d=%22M1753.937,1136.666C2145.058,1136.666 2462.598,1454.207 2462.598,1845.328C2462.598,2236.449 2145.058,2553.989 1753.937,2553.989C1362.816,2553.989 1045.276,2236.449 1045.276,1845.328C1045.276,1454.207 1362.816,1136.666 1753.937,1136.666ZM1753.937,1284.304C1444.3,1284.304 1192.913,1535.69 1192.913,1845.328C1192.913,2154.965 1444.3,2406.351 1753.937,2406.351C2063.574,2406.351 2314.961,2154.965 2314.961,1845.328C2314.961,1535.69 2063.574,1284.304 1753.937,1284.304Z%22 fill=%22%23fff%22/%3E%3C/svg%3E");
  --dr-pulse:1.6s;
  /* the skeletons' shine (Justin 2026-10-29): one sweep across the whole screen this often (its pass is the first 60 %,
     then a rest); kit/base.js SHINE_CSS */
  --dr-shine-period:3s;
  /* a picture fading in once it has loaded (a live preview, a thumbnail) */
  --dr-fade:.35s;
  /* one sweep of a progress bar that can't say how far it is */
  --dr-wait:1.4s;
  /* a list row lighting up to say "here it is" */
  --dr-seek:1.2s;
  /* a phone bottom sheet sliding up (desktop popovers stay instant) */
  --dr-sheet:.18s;
  /* no motion (reduced motion) */
  --dr-instant:0s;
  /* easing (Material 3 standard curves): arriving, leaving */
  --dr-ease-out:cubic-bezier(.2, 0, 0, 1);
  --dr-ease-in:cubic-bezier(.4, 0, 1, 1);

  /* ---- layers: every stacking order outside a component's own inside (1-6 there stay local). The numbers keep
     today's order with the old-kit overlays that share a document (Advisor 9999, Ask 10000) until they're rebuilt ---- */
  --dr-z-raised:1;
  --dr-z-sticky:10;
  --dr-z-dock:20;
  --dr-z-popover:1000;
  --dr-z-dialog:1100;
  --dr-z-toast:1200;
  /* the app shell's tab bar over the page below it */
  --dr-z-shell:9001;
  --dr-z-tooltip:10050;
  /* the lock screen (kit/lock.js): over everything, tooltips too */
  --dr-z-lock:20000;
  /* the phone's cover while the page is hidden (kit/lock.js): over the lock screen too */
  --dr-z-cover:20001;

  /* ---- old names (aliases until every branch has run scripts/kit_tokens_migrate.py; tests/ui/uit_tokens.py
     fails a use of them in ui/) ---- */
  --dr-text-body:var(--dr-text-sec);
  --dr-text-icon:var(--dr-text-sec);
  --dr-text-2:var(--dr-text-ter);
  --dr-text-3:var(--dr-text-ter);
  --dr-text-off:var(--dr-text-dis);
  --dr-fs-kbd:var(--dr-fs-xs);
  --dr-fs-cap:var(--dr-fs-s);
  --dr-fs-btn:var(--dr-fs);
  --dr-canvas:var(--dr-ground);
  --dr-bar:var(--dr-ground);
  --dr-card:var(--dr-panel);
  --dr-raised-2:var(--dr-raised);
  --dr-field:var(--dr-control);
  --dr-hover-2:var(--dr-hover);
  --dr-hover-3:var(--dr-hover);
  --dr-selected-card:var(--dr-selected);
  --dr-line-2:var(--dr-line);
  --dr-line-3:var(--dr-line-bold);
  --dr-line-4:var(--dr-line-bold);
  --dr-line-5:var(--dr-line-bold);
  --dr-r-s:var(--dr-r-xs);
  --dr-r:var(--dr-r-chip);
  --dr-r-l:var(--dr-r-m);

  color-scheme:dark;
}

/* a page that uses the kit: the ground, the font and the base size */
html.dr, .dr-page {
  font-family:var(--dr-font); font-size:var(--dr-fs); line-height:var(--dr-lh); color:var(--dr-text);
  background:var(--dr-ground); -webkit-font-smoothing:antialiased;
}

/* a page's own plain text box, dropdown or text area (class dr-in): the kit's field look (base.js fieldCss), its
   error (aria-invalid) and disabled states; the phone's 44 px height */
.dr-in { box-sizing:border-box; width:100%; min-width:0; height:var(--dr-ctl); font:inherit; color:var(--dr-text); background:var(--dr-field);
  border:1px solid var(--dr-line-strong); border-radius:var(--dr-r); padding:0 var(--dr-sp-2); text-overflow:ellipsis; }
textarea.dr-in { height:auto; min-height:var(--dr-ctl); padding:var(--dr-sp-1) var(--dr-sp-2); }
.dr-in::placeholder { color:var(--dr-text-ter); }
.dr-in:hover:not(:focus):not(:disabled) { border-color:var(--dr-line-strong-hover); }
.dr-in:focus { outline:none; }
.dr-in:focus-visible, select.dr-in:focus { outline:var(--dr-focus-ring); outline-offset:var(--dr-focus-gap); }
.dr-in[aria-invalid=true] { border-color:var(--dr-bad); }
.dr-in:disabled { border-color:var(--dr-line); background:none; color:var(--dr-text-dis); cursor:not-allowed; }
.dr-phone .dr-in, html.dr-phone .dr-in { height:var(--dr-field-touch); font-size:var(--dr-fs-l); line-height:var(--dr-lh-l); }
/* checkboxes on kit pages: the strong edge (3:1), the accent when ticked, the focus ring */
html.dr input[type=checkbox] { appearance:none; flex:none; width:var(--dr-icon); height:var(--dr-icon); margin:0; border:1px solid var(--dr-line-strong);
  border-radius:var(--dr-r-xs); background:var(--dr-field) center / 12px no-repeat; cursor:pointer; vertical-align:middle; }
html.dr input[type=checkbox]:hover { border-color:var(--dr-line-strong-hover); }
html.dr input[type=checkbox]:checked { background-color:var(--dr-acc); border-color:var(--dr-acc); background-image:var(--dr-check); }
html.dr input[type=checkbox]:focus-visible { outline:var(--dr-focus-ring); outline-offset:var(--dr-focus-gap); }
html.dr input[type=checkbox]:disabled { border-color:var(--dr-line); background-color:transparent; cursor:not-allowed; }

/* scrollbars: a slim rounded thumb, no track; it brightens and widens a little under the pointer */
::-webkit-scrollbar { width:10px; height:10px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background:transparent; }
::-webkit-scrollbar-thumb { background:var(--dr-scroll); border:3px solid transparent; border-radius:6px; background-clip:padding-box; min-height:32px; min-width:32px; }
::-webkit-scrollbar-thumb:hover { background-color:var(--dr-scroll-hover); border-width:2px; }
::-webkit-scrollbar-thumb:active { background-color:var(--dr-scroll-active); border-width:2px; }
@supports not selector(::-webkit-scrollbar) { * { scrollbar-width:thin; scrollbar-color:var(--dr-scroll) transparent; } }

/* reduced motion: state changes snap on pages too (base.js says the same inside components) */
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration:var(--dr-instant) !important; } }

/* reduced motion: the spinner turns three times slower */
@media (prefers-reduced-motion: reduce) {
  :root { --dr-spinner:url("data:image/svg+xml,%3Csvg viewBox=%221045.275591 1136.66641 1418 1418%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cdefs%3E%3CclipPath id=%22dr-eclipse%22%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22480%22/%3E%3C/clipPath%3E%3C/defs%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22595.744%22 fill=%22%23000%22/%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22472.441%22 fill=%22%23f59a3c%22/%3E%3Cg clip-path=%22url(%23dr-eclipse)%22%3E%3Cg%3E%3CanimateTransform attributeName=%22transform%22 type=%22rotate%22 values=%220.00 1439.67 987.54%3B-60.42 1439.67 987.54%3B-299.58 1439.67 987.54%3B-360.00 1439.67 987.54%22 keyTimes=%220.0000%3B0.4600%3B0.5400%3B1.0000%22 calcMode=%22spline%22 keySplines=%220.6 0 0.9 0.5%3B0 0 1 1%3B0.1 0.5 0.4 1%22 dur=%226.6s%22 repeatCount=%22indefinite%22/%3E%3Ccircle cx=%221753.937%22 cy=%221845.328%22 r=%22442.913%22 fill=%22%23000%22%3E%3Canimate attributeName=%22r%22 values=%22480.4%3B442.9%3B442.9%3B480.4%22 keyTimes=%220.0000%3B0.3219%3B0.6781%3B1.0000%22 dur=%226.6s%22 repeatCount=%22indefinite%22/%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3Cpath d=%22M1753.937,1136.666C2145.058,1136.666 2462.598,1454.207 2462.598,1845.328C2462.598,2236.449 2145.058,2553.989 1753.937,2553.989C1362.816,2553.989 1045.276,2236.449 1045.276,1845.328C1045.276,1454.207 1362.816,1136.666 1753.937,1136.666ZM1753.937,1284.304C1444.3,1284.304 1192.913,1535.69 1192.913,1845.328C1192.913,2154.965 1444.3,2406.351 1753.937,2406.351C2063.574,2406.351 2314.961,2154.965 2314.961,1845.328C2314.961,1535.69 2063.574,1284.304 1753.937,1284.304Z%22 fill=%22%23fff%22/%3E%3C/svg%3E"); }
}

/* ---- the lock screen's face (Justin 2026-10-21: (a) Quiet + the glow, plan/mockups/lock/lock-looks.html look d): the
   kit's (kit/lock.js), the phone's (phone/app.js) and the shell's (shell/topbar.js) all wear it ---- */
.dr-lockface { position:fixed; inset:0; z-index:var(--dr-z-lock); display:flex; flex-direction:column; align-items:center; justify-content:center;
  background:var(--dr-ground); color:var(--dr-text); font-family:var(--dr-font); font-size:var(--dr-fs); line-height:var(--dr-lh-base); }
/* the keyboard up (a phone, kit/lock.js fit): the face covers only the visual viewport, easing as the keyboard comes and goes */
.dr-lockface.fit { inset:auto 0; top:var(--lf-top, 0); height:var(--lf-h, 100%);
  transition:top var(--dr-sheet) var(--dr-ease-out), height var(--dr-sheet) var(--dr-ease-out); }
.dr-lockface form { box-sizing:border-box; display:flex; flex-direction:column; align-items:center; gap:var(--dr-sp-4); width:min(340px, calc(100vw - 2 * var(--dr-gutter))); margin:0; }
.dr-lockface .lf-mark { position:relative; width:40px; height:40px; }
/* the glow: soft orange (18 % at the middle), breathing over 4.8 s; still under reduced motion */
.dr-lockface .lf-mark::before { content:""; position:absolute; left:50%; top:50%; width:200px; height:200px; margin:-100px 0 0 -100px; border-radius:50%; pointer-events:none;
  background:radial-gradient(circle, #f59a3c2e 0%, #f59a3c12 34%, #8b9cff0a 52%, transparent 70%); animation:dr-lock-breathe 4.8s ease-in-out infinite; }
.dr-lockface .lf-mark::after { content:""; position:absolute; inset:0; background:var(--dr-mark) center / contain no-repeat; filter:drop-shadow(0 0 10px #f59a3c40); }
/* the moon <-> padlock mark (kit/lock-mark.js) in its place, where the kit draws it */
.dr-lockface .lf-mark.anim::after { display:none; }
.dr-lockface .lf-mark svg { position:relative; display:block; width:100%; height:100%; filter:drop-shadow(0 0 10px #f59a3c40); }
.dr-lockface .lf-mark.wrong svg { animation:dr-lock-flash 600ms ease-in-out; }
@keyframes dr-lock-breathe { 50% { transform:scale(1.08); opacity:.7; } }
@media (prefers-reduced-motion: reduce) { .dr-lockface .lf-mark::before { animation:none; } }
/* a wrong password (Justin 2026-10-21): the orange flashes to the error red and back (600 ms) and the mark shakes a
   little (3 swings, 6 px, 400 ms), the glow tinted red with it; the field never moves. Reduced motion: the flash only */
.dr-lockface .lf-mark.wrong { animation:dr-lock-shake 400ms ease-in-out; }
.dr-lockface .lf-mark.wrong::after { animation:dr-lock-flash 600ms ease-in-out; }
.dr-lockface .lf-mark.wrong::before { animation:dr-lock-breathe 4.8s ease-in-out infinite, dr-lock-flash-glow 600ms ease-in-out; }
@keyframes dr-lock-shake { 0%, 100% { translate:0; } 17% { translate:-6px; } 33% { translate:6px; } 50% { translate:-5px; } 67% { translate:4px; } 83% { translate:-2px; } }
@keyframes dr-lock-flash { 30%, 55% { filter:drop-shadow(0 0 12px #e5484d66) hue-rotate(-32deg) saturate(1.8); } }
@keyframes dr-lock-flash-glow { 30%, 55% { filter:hue-rotate(-32deg) saturate(1.8); } }
@media (prefers-reduced-motion: reduce) {
  .dr-lockface .lf-mark.wrong { animation:none; }
  .dr-lockface .lf-mark.wrong::before { animation:dr-lock-flash-glow 600ms ease-in-out; }
}
.dr-lockface h1 { position:relative; margin:0; font-size:var(--dr-fs-l); line-height:var(--dr-lh-l); font-weight:var(--dr-fw-m); color:var(--dr-text); }
.dr-lockface .lf-field { box-sizing:border-box; width:100%; height:44px; display:flex; align-items:center; gap:var(--dr-sp-2); padding:0 var(--dr-sp-1) 0 var(--dr-sp-3);
  border-radius:var(--dr-r-m); background:var(--dr-field); border:1px solid var(--dr-line-strong); }
/* (focused: the field's own edge is the ring, one edge, not a ring around a border: QA 2026-10-21; 1 px after a tap or
   click, 2 px by keyboard: QA 2026-10-25, every field's tokens) */
.dr-lockface .lf-field:focus-within { outline:none; border-color:var(--dr-field-focus); box-shadow:var(--dr-field-focus-more); }
.dr-lockface .lf-field.bad { border-color:var(--dr-bad); }
/* (a wrong password: the red edge is the one ring, no focus ring outside it) */
.dr-lockface .lf-field.bad:focus-within { outline:none; border-color:var(--dr-bad); box-shadow:none; }
.dr-lockface .lf-field input { flex:1; min-width:0; height:100%; background:none; border:0; outline:none; color:var(--dr-text); font:inherit; font-size:var(--dr-fs-l); }
.dr-lockface .lf-go { flex:none; height:34px; padding:0 var(--dr-sp-3); border-radius:var(--dr-r-s); border:0; background:var(--dr-acc); color:var(--dr-on-acc);
  font:inherit; font-weight:var(--dr-fw-m); cursor:pointer; }
.dr-lockface .lf-go:focus-visible { outline:var(--dr-focus-ring); outline-offset:var(--dr-focus-gap); }
.dr-lockface .lf-go:disabled { background:var(--dr-raised); color:var(--dr-text-ter); cursor:default; }
.dr-lockface .lf-msg { margin:0; min-height:var(--dr-lh-s); font-size:var(--dr-fs-s); line-height:var(--dr-lh-s); color:var(--dr-bad-text); text-align:center; }
.dr-lockface .lf-alt { border:0; background:none; padding:var(--dr-sp-1); color:var(--dr-text-ter); font:inherit; font-size:var(--dr-fs-s); line-height:var(--dr-lh-s); cursor:pointer; }
.dr-lockface .lf-alt:hover { color:var(--dr-text); }
.dr-lockface .lf-foot { position:absolute; left:0; right:0; bottom:calc(var(--dr-sp-5) + env(safe-area-inset-bottom, 0px)); display:flex; justify-content:center; align-items:center; gap:var(--dr-sp-3);
  color:var(--dr-text-ter); font-size:var(--dr-fs-s); line-height:var(--dr-lh-s); }
.dr-lockface .lf-foot button { border:0; background:none; padding:var(--dr-sp-2) var(--dr-sp-1); color:var(--dr-text-ter); font:inherit; text-decoration:underline; text-underline-offset:3px; cursor:pointer; }
.dr-lockface .lf-foot button:hover { color:var(--dr-text); }
html.dr-phone .dr-lockface .lf-go { height:36px; }

/* focus rings after a click or tap: none, even once a hotkey is pressed (kit/dr.js sets html[data-focus=pointer]; Tab
   or F6 clears it). Last in the file, so it wins over every theme's --dr-focus */
:root[data-focus="pointer"] { --dr-focus:transparent; --dr-field-focus-more:none; }
