/* GENERATED from src/tokens.json (kit 1.0.0) by tools/build.mjs. Do not edit: change tokens.json and rebuild. */
:root {
  --e-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --e-t-caption: 12.5px;
  --e-t-label: 14px;
  --e-t-body: 16px;
  --e-t-title: 21px;
  --e-t-display: 36px;
  --e-ink: #fff;
  --e-ink-2: #fff;
  --e-ink-3: #fff;
  --e-on-ink: #17161a;
  --e-pane: rgba(22, 22, 26, 0.55);
  --e-pane-blur: blur(18px) saturate(1.25);
  --e-pane-tint: rgba(8, 8, 10, 0.26);
  --e-well: rgba(0, 0, 0, 0.30);
  --e-well-deep: rgba(0, 0, 0, 0.42);
  --e-lip-dark: rgba(0, 0, 0, 0.55);
  --e-lip-light: rgba(255, 255, 255, 0.11);
  --e-hair: rgba(255, 255, 255, 0.10);
  --e-fill: #35c46a;
  --e-drain: #ec4a3f;
  --e-r-pane: 22px;
  --e-r-ctl: 12px;
  --e-hit: 44px;
  --e-track: 6px;
  --e-thumb: 24px;
  --e-tint-ruby: #f70001;
  --e-tint-amber: #ebb900;
  --e-tint-citrine: #fff912;
  --e-tint-emerald: #00f700;
  --e-tint-teal: #0aa3a3;
  --e-tint-sapphire: #1f4fd8;
  --e-tint-amethyst: #7a3fd1;
  --e-tint-rose: #e0457b;
}

/* ember-ui.css — the standard controls for Blair's apps (Pulse, Sun, the assistant).
 *
 * Written 2026-09-22. Why each choice was made, and the research behind it:
 *   /home/blair/shared/vm/UI-STANDARD-2026-09-22.md
 * Live specimens, over the real glass shader:  https://sun-blair.duckdns.org/ui-lab/
 *
 * The one idea: the glass pane is the material, and controls are PRESSED INTO it
 * (inset wells), never floated on top of it as more glass. Exactly one thing per
 * surface is raised: the primary action. Depth carries hierarchy, not colour and
 * not glow.
 *
 * Hard rules, because each is a documented tell of generated UI:
 *   - no coloured glows, ever (box-shadow is for depth, and depth is black);
 *   - labels in sentence case, never tracked-out capitals;
 *   - no "A · B · C" meta strings: use layout (a line break, a second column);
 *   - colour is data. Red and green mean emptying and filling, nothing else.
 *
 *
 * Type (revised 2026-10-09, Blair: "eliminate AI tells (0 with a slash is one of the
 * most obvious)"). The kit shipped Atkinson Hyperlegible Next, whose zero is slashed:
 * in a numbers-heavy UI that one glyph reads as generated. It now uses the platform's
 * own face (SF Pro on iPhone, Roboto on Android, Segoe UI on Windows): no download, no
 * third-party request (rule 21), and nothing a reader associates with templated UI.
 *
 * Ink (same day, Blair: "No light beige or off white text, if you need light text just
 * make it white"). All three ink steps are pure white; hierarchy comes from size and
 * weight, never from a warmer or greyer white.
 */

/* Every value below comes from a CSS variable defined in tokens.css, which is generated
   from /home/blair/ui-kit/src/tokens.json. There are no literals to override here: to
   change a size, a colour or a font, change the token. */

/* ------------------------------------------------------------------ pane */
.e-pane {
  border-radius: var(--e-r-pane);
  padding: 16px;
  color: var(--e-ink);
  font-family: var(--e-font);
  background: var(--e-pane);
  -webkit-backdrop-filter: var(--e-pane-blur);
  backdrop-filter: var(--e-pane-blur);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 10px 30px rgba(0, 0, 0, 0.35);
}
/* Where the WebGL shader draws the glass (data-glass), the element adds only a light
   smoke tint: enough that a caption survives a bright tower refracting behind it,
   little enough that the refraction still reads as glass. */
.e-pane[data-glass] { background: var(--e-pane-tint); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }

/* ------------------------------------------------------------------ type */
.e-display { font: 700 var(--e-t-display)/1.05 var(--e-font); letter-spacing: -0.015em; font-variant-numeric: tabular-nums; }
.e-title   { font: 700 var(--e-t-title)/1.2 var(--e-font); letter-spacing: -0.005em; }
.e-body    { font: 400 var(--e-t-body)/1.5 var(--e-font); color: var(--e-ink-2); }
.e-label   { font: 600 var(--e-t-label)/1.2 var(--e-font); color: var(--e-ink-2); }
.e-caption { font: 400 var(--e-t-caption)/1.4 var(--e-font); color: var(--e-ink-3); }
.e-num     { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ buttons */
.e-btn {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 16px;
  border: 0; border-radius: var(--e-r-ctl);
  font: 600 15px/1 var(--e-font); color: var(--e-ink);
  background: var(--e-well);
  box-shadow: inset 0 1.5px 2px var(--e-lip-dark), inset 0 -1px 0 var(--e-lip-light);
  cursor: pointer; touch-action: manipulation;
  transition: background .12s, box-shadow .12s, transform .08s;
}
.e-btn:active { background: var(--e-well-deep);
  box-shadow: inset 0 2.5px 4px var(--e-lip-dark), inset 0 -1px 0 var(--e-lip-light); transform: translateY(.5px); }
.e-btn--pill { border-radius: 999px; }

/* The ONE raised control on a surface. It stands out of the glass instead of into it. */
.e-btn--primary {
  color: var(--e-on-ink);
  background: var(--e-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 1px 1px rgba(0, 0, 0, 0.35), 0 4px 10px rgba(0, 0, 0, 0.30);
}
.e-btn--primary:active { background: #e6e6e6; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25), 0 1px 1px rgba(0, 0, 0, 0.3); }

.e-btn--icon { width: var(--e-hit); height: var(--e-hit); min-height: 0; padding: 0; border-radius: 50%; }
.e-btn--icon svg { width: 20px; height: 20px; }

.e-btn:disabled, .e-btn[aria-disabled="true"] { opacity: .42; cursor: not-allowed; transform: none; }
.e-btn:focus-visible, .e-seg button:focus-visible, .e-range:focus-visible, .e-toggle input:focus-visible + span {
  outline: 2px solid var(--e-ink); outline-offset: 2px; }

/* ------------------------------------------------------------------ segmented control */
.e-seg {
  display: inline-flex; padding: 3px; gap: 2px;
  border-radius: var(--e-r-ctl);
  background: var(--e-well);
  box-shadow: inset 0 1.5px 2px var(--e-lip-dark), inset 0 -1px 0 var(--e-lip-light);
}
.e-seg button {
  -webkit-appearance: none; appearance: none; border: 0; cursor: pointer;
  min-height: 34px; padding: 0 14px; border-radius: 9px;
  font: 600 14px/1 var(--e-font); color: var(--e-ink-2); background: transparent;
}
.e-seg button[aria-pressed="true"] {
  color: var(--e-ink);
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* ------------------------------------------------------------------ slider
 * Markup:
 *   <div class="e-field">
 *     <label class="e-label" for="speed">Speed</label>
 *     <output class="e-value" for="speed">1×</output>
 *     <input class="e-range" id="speed" type="range" min="0" max="4" step="1" value="1">
 *     <div class="e-ticks"><span>½×</span><span>1×</span><span>2×</span><span>4×</span><span>8×</span></div>
 *   </div>
 * ember-ui.js keeps --pct in step with the value, which paints the filled part.
 * The track is a groove in the glass; the thumb is the only raised object on it.
 */
.e-field {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline;
  row-gap: 6px; column-gap: 12px;
}
.e-field > .e-range, .e-field > .e-ticks { grid-column: 1 / -1; }
.e-value { font: 700 16px/1 var(--e-font); color: var(--e-ink); font-variant-numeric: tabular-nums; }

.e-range {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: var(--e-hit); margin: -10px 0; /* 44px hit area, 24px of it visual */
  background: transparent; cursor: pointer; touch-action: pan-y;
  --pct: 50%;
}
.e-range::-webkit-slider-runnable-track {
  height: var(--e-track); border-radius: calc(var(--e-track) / 2);
  background: linear-gradient(90deg, var(--e-ink-2) 0 var(--pct), var(--e-well) var(--pct) 100%);
  box-shadow: inset 0 1px 2px var(--e-lip-dark), 0 1px 0 var(--e-lip-light);
}
.e-range::-moz-range-track {
  height: var(--e-track); border-radius: calc(var(--e-track) / 2); background: var(--e-well);
  box-shadow: inset 0 1px 2px var(--e-lip-dark), 0 1px 0 var(--e-lip-light);
}
.e-range::-moz-range-progress { height: var(--e-track); border-radius: calc(var(--e-track) / 2); background: var(--e-ink-2); }
.e-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: var(--e-thumb); height: var(--e-thumb); margin-top: calc((var(--e-track) - var(--e-thumb)) / 2); border-radius: 50%; border: 0;
  background: var(--e-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 1px 2px rgba(0, 0, 0, 0.5), 0 3px 8px rgba(0, 0, 0, 0.3);
}
.e-range::-moz-range-thumb {
  width: var(--e-thumb); height: var(--e-thumb); border-radius: 50%; border: 0; background: var(--e-ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 3px 8px rgba(0, 0, 0, 0.3);
}
.e-range:active::-webkit-slider-thumb { transform: scale(1.08); }

/* Tick labels sit under the detents. Space-between puts the first and last at the ends
   of the track; the thumb's 12px radius is absorbed by the 12px side padding. */
.e-ticks { display: flex; justify-content: space-between; padding: 0 4px;
  font: 400 var(--e-t-caption)/1 var(--e-font); color: var(--e-ink-3); font-variant-numeric: tabular-nums; }
.e-ticks span { min-width: 24px; text-align: center; }
.e-ticks span[aria-current="true"] { color: var(--e-ink); font-weight: 700; }

/* ------------------------------------------------------------------ toggle */
.e-toggle { position: relative; display: inline-flex; align-items: center; gap: 12px; cursor: pointer;
  font: 600 var(--e-t-label)/1.2 var(--e-font); color: var(--e-ink-2); min-height: var(--e-hit); }
.e-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.e-toggle > input + span { position: relative; width: 46px; height: 28px; border-radius: 999px; flex: none;
  background: var(--e-well); box-shadow: inset 0 1.5px 2px var(--e-lip-dark), inset 0 -1px 0 var(--e-lip-light);
  transition: background .15s; }
.e-toggle > input + span::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--e-ink-2); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); transition: transform .15s, background .15s; }
.e-toggle input:checked + span { background: rgba(255, 255, 255, 0.28); }
.e-toggle input:checked + span::after { transform: translateX(18px); background: var(--e-ink); }

/* ------------------------------------------------------------------ legend key
 * A flat disc with a dark ring so it reads on light and dark maps. No glow: a glow on
 * a legend dot says "live status light", which a legend is not. */
.e-key { display: inline-flex; align-items: center; gap: 8px;
  font: 400 var(--e-t-caption)/1.3 var(--e-font); color: var(--e-ink-2); }
.e-key i { width: 11px; height: 11px; border-radius: 50%; flex: none; background: currentColor;
  box-shadow: 0 0 0 1.5px rgba(0, 0, 0, 0.45); }
.e-key--fill i { color: var(--e-fill); }
.e-key--drain i { color: var(--e-drain); }

@media (prefers-reduced-motion: reduce) {
  .e-btn, .e-toggle span, .e-toggle > input + span::after { transition: none; }
}

/* ================================================================== the glass skin
 * Every control has two skins. WELL (above, the default) presses the control into
 * the pane as a dark inset. GLASS makes the control its own piece of glass,
 * flush-mounted in a hole in the pane: the shader draws the button's lens, the seam
 * and the hole's bevel (src/glass/core.glsl.js), and the element itself becomes
 * transparent so only its label is left on top.
 *
 * Choose per region:  <div class="e-pane" data-glass data-skin="glass"> ... </div>
 * ember-ui.js then marks the controls inside with data-glass="button". Add
 * data-tint="ruby" (or any palette name or #hex) to stain one.
 *
 * Everything here is scoped under body.lg, which the glass host sets only once its
 * shader is running. Without it a glass-skin control is simply a well, so a phone
 * that cannot run the shader never gets an invisible button.
 */
.e-glass-knob { display: none; }

body.lg .e-btn[data-glass="button"]:not([data-glass-off]),
body.lg .e-seg button[data-glass="button"]:not([data-glass-off]) {
  background: transparent; box-shadow: none; transform: none;
  color: var(--e-glass-ink, var(--e-ink));
}
/* press feedback comes from the shader (the button sinks and the seam deepens) */
/* a stained PANE tells its own text which ink to use */
body.lg .e-pane[data-glass][data-tint] { color: var(--e-glass-ink, var(--e-ink)); }
body.lg .e-btn[data-glass="button"]:not([data-glass-off]):active { background: transparent; box-shadow: none; }

/* toggle: the track stays a groove, the knob is glass */
body.lg .e-toggle span:has(> .e-glass-knob)::after { opacity: 0; }
body.lg .e-toggle .e-glass-knob {
  display: block; position: absolute; top: 2px; left: 2px; width: 24px; height: 24px;
  border-radius: 50%; pointer-events: none; transition: transform .15s;
}
body.lg .e-toggle input:checked + span .e-glass-knob { transform: translateX(18px); }

/* slider: identical in both skins. The thumb stays opaque (Blair, 2026-10-09). */

/* a knob the shader had no room for: draw it as the ordinary white thumb */
body.lg .e-glass-knob[data-glass-off] { background: var(--e-ink); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); }
