/* 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:
 *   (internal path)
 * Live specimens, over the real glass shader:  (dev server)
 *
 * 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.
 *
 * Self-hosted font (no Google request at page load: rule 21, and it works offline).
 * Atkinson Hyperlegible Next, Braille Institute, SIL Open Font License. Chosen because
 * every one of these apps sets small text over a busy night photo or a map, which is
 * the exact problem the face was drawn to solve: letterforms that cannot be confused.
 */

@font-face { font-family: "Atkinson Hyperlegible Next"; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url("fonts/ahn-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Atkinson Hyperlegible Next"; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url("fonts/ahn-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Atkinson Hyperlegible Next"; font-style: italic; font-weight: 200 800; font-display: swap;
  src: url("fonts/ahn-latin-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  /* type */
  --e-font: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", sans-serif;
  --e-t-caption: 12.5px;   /* units, legends, footnotes */
  --e-t-label: 14px;       /* control labels */
  --e-t-body: 16px;
  --e-t-title: 21px;
  --e-t-display: 36px;     /* the one big number on a screen */

  /* ink: warm paper white, three steps, never pure #fff */
  --e-ink: #f2efe8;
  --e-ink-2: #c7c2b8;
  --e-ink-3: #99948a;
  --e-on-ink: #17161a;     /* text on the raised (ink-filled) control */

  /* surfaces */
  --e-pane: rgba(22, 22, 26, 0.55);          /* CSS-glass fallback fill */
  --e-pane-blur: blur(18px) saturate(1.25);
  --e-well: rgba(0, 0, 0, 0.30);             /* an inset control's floor */
  --e-well-deep: rgba(0, 0, 0, 0.42);        /* pressed */
  --e-lip-dark: rgba(0, 0, 0, 0.55);         /* top inner edge of a well: in shadow */
  --e-lip-light: rgba(255, 255, 255, 0.11);  /* bottom inner edge: catches the light */
  --e-hair: rgba(255, 255, 255, 0.10);

  /* data semantics — used for meaning only */
  --e-fill: #35c46a;       /* filling / go */
  --e-drain: #ec4a3f;      /* draining / stop */

  /* geometry: radius encodes nesting (pane > control), never one radius for all */
  --e-r-pane: 22px;
  --e-r-ctl: 12px;
  --e-hit: 44px;           /* minimum touch target (Apple HIG) */
}

/* ------------------------------------------------------------------ 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: rgba(8, 8, 10, 0.24); -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: #dcd8cf; 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(242, 239, 232, 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: 6px; border-radius: 3px;
  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: 6px; border-radius: 3px; 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: 6px; border-radius: 3px; background: var(--e-ink-2); }
.e-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 24px; height: 24px; margin-top: -9px; 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: 24px; height: 24px; 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 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 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(242, 239, 232, 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 span::after { transition: none; }
}
