/* Vanity: the project preset (roles re-pointed to the owner's Design System.dc.html) and the page layout.
   Components come from kit/components.css and read these roles.
   Rules (research 2026-11-08, see DESIGN.md): one ink element per view (Start); selection is a tone step;
   secondary actions are a tone-step fill; labels uppercase over tabular figures; 8-12 inside a group,
   24 between groups, 32 between sections. */

@font-face { font-family: "Geist"; src: url("/fonts/geist.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/fonts/geist-mono.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Schibsted Grotesk"; src: url("/fonts/schibsted-grotesk.woff2") format("woff2"); font-weight: 400 900; font-display: swap; }

/* ---------------------------------------------------------------- Preset: roles */
:root {
  color-scheme: dark;
  /* 2026-11-09 reskin to the approved Astryx demo landing: tinted near-black steps, one lime accent */
  --ground: #08090b;
  --surface: #171719;
  --raised: #212124;
  --raised-hover: #2a2a2e;
  --raised-active: #333338;
  --overlay: #1c1c1f;
  --panel-line: #2a2a2e; /* the system's 1px panel border: identity, recorded in DESIGN.md */
  --line-row: #232326; /* list rows only */
  --line: #66666c; /* field and control edges, 3:1 on ground and surface */
  --text-strong: #ededed;
  --text-body: #cfcfcf;
  --text-dim: #8f8f94;
  /* One accent, four roles: Start, the matched pattern in the hero address, focus, live state */
  --accent: #c8f169;
  --accent-hover: #d6f78a;
  --accent-ink: #08090b;
  --accent-text: #c8f169;
  --accent-soft: #c8f16914;
  --focus: #c8f169;
  --font-display: "Schibsted Grotesk", "Geist", system-ui, sans-serif;
  --veil: #ffffff0d;
  --scrim: #000000;
  --positive: oklch(0.78 0.15 150);
  --negative: oklch(0.72 0.17 25);
  --warning: oklch(0.8 0.14 80);
  --info: oklch(0.76 0.12 240);
  --radius-control: 0.5rem; /* 8 */
  --radius-panel: 0.875rem; /* 14: the system's panel radius */
  --hit: 2.75rem;
  --control-xl: 2.75rem; /* 44: main fields, segments and the primary action */
  --gutter: var(--s-4);
}

@media (min-width: 640px) {
  :root { --gutter: var(--s-6); }
}

html { scrollbar-gutter: stable; }

body {
  background: var(--ground);
  color: var(--text-body);
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

[hidden] { display: none !important; }

/* Labels: the system's small uppercase caption over a figure (identity, DESIGN.md) */
.label,
.figures dt,
.budget dt,
.job-stats dt,
.field-label {
  color: var(--text-dim);
  font-size: var(--type-label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- Shell */
.wrap {
  width: 100%;
  max-width: calc(45rem + 2 * var(--gutter)); /* 720 content */
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.topbar {
  border-bottom: 1px solid var(--line-row);
  background: var(--ground);
}

.topbar .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  height: var(--header-height);
}

.crumb {
  color: var(--text-strong);
  font: 600 var(--type-small) / 1 var(--font-mono);
  letter-spacing: 0.14em;
}

.account-nav { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }

.account-name {
  overflow: hidden;
  color: var(--text-dim);
  font-size: var(--type-small);
  text-overflow: ellipsis;
  white-space: nowrap;
}

main.wrap {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  padding-block: var(--s-5) var(--s-8);
}

/* View switch: a segmented well at the top of the content column, sticky while scrolling */
.views {
  position: sticky;
  top: 0;
  z-index: 10;
  padding-block: var(--s-2);
  margin-block: calc(var(--s-2) * -1);
  background: var(--ground);
}

.view {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  min-height: 24rem;
  animation: view-in var(--duration-quick) var(--ease-out);
}

@keyframes view-in { from { opacity: 0; } }

.tab-count {
  color: var(--text-dim);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.views-seg .dot { color: var(--info); margin-left: var(--s-1); border-radius: var(--radius-pill); }

.intro { display: flex; flex-direction: column; gap: var(--s-2); }

.intro h1 {
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: 2rem; /* 32 at 390 */
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  text-wrap: balance;
}

@media (min-width: 640px) {
  .intro h1 { font-size: 2.75rem; } /* 44 */
}

.intro { gap: var(--s-2); }
.intro p { text-wrap: pretty; }

/* The composer sits on the dither field: the approved landing's signature */
.field-wrap {
  position: relative;
  isolation: isolate;
  padding: var(--s-3);
  border-radius: calc(var(--radius-panel) + var(--s-3));
  background: var(--ground);
  overflow: hidden;
}

@media (min-width: 640px) {
  .field-wrap { padding: var(--s-4); border-radius: calc(var(--radius-panel) + var(--s-4)); }
}

.field-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* Paper Shaders' own canvas rules (its injected <style> is blocked by the CSP) */
:where([data-paper-shader]) { isolation: isolate; }
[data-paper-shader] canvas {
  contain: strict;
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.field-wrap > .composer {
  position: relative;
  z-index: 1;
  border-radius: var(--radius-panel);
  background: var(--surface);
}

.intro p { max-width: 60ch; color: var(--text-dim); }

.panel { border: 1px solid var(--panel-line); }

/* ---------------------------------------------------------------- Groups */
.group { display: flex; flex-direction: column; gap: var(--s-3); }
.group-lg { display: flex; flex-direction: column; gap: var(--s-5); }

.pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}

/* ---------------------------------------------------------------- Composer */
.composer {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding: var(--s-4);
}

@media (min-width: 640px) {
  .composer { padding: var(--s-5); }
}

/* The address is the hero: two fixed rows of 22, sized to its own container, never truncated */
.preview {
  container-type: inline-size;
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-4);
  border-radius: var(--radius-control);
  background: var(--ground);
}

.address {
  width: max-content;
  max-width: 100%;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: min(2rem, calc((100cqi - 1rem) / 14));
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0;
  overflow-wrap: anywhere;
}

.address > .line { display: block; white-space: nowrap; }
.address .pat { color: var(--accent); font-weight: 650; }

/* List addresses: one line, cut in the middle, the match always visible */
.address.is-small {
  width: auto;
  font-size: var(--type-body);
  line-height: var(--leading-tight);
  white-space: nowrap;
}

.field { gap: var(--s-2); }

.field-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2);
}

.chars-left {
  color: var(--text-dim);
  font-size: var(--type-label);
  font-variant-numeric: tabular-nums;
}

.composer .input,
.dialog .input {
  height: var(--control-xl);
  background: var(--ground);
}

.composer .input { font-family: var(--font-mono); }

/* Hint and error share one slot that reserves two lines, so nothing below moves */
.composer .field-hint,
.composer .field-error {
  min-height: calc(2 * var(--type-label) * var(--leading-tight));
  align-items: flex-start;
}

@media (min-width: 640px) {
  .composer .field-hint,
  .composer .field-error { min-height: calc(var(--type-label) * var(--leading-tight)); }
}

.field-error { color: var(--text-body); }
.field-error .dot,
.field-note .dot { margin-top: 0.3rem; color: var(--negative); }

.field-note {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  min-height: calc(var(--type-label) * var(--leading-tight));
  color: var(--text-body);
  font-size: var(--type-small);
}

/* Segmented controls: equal segments in a well; the selected one is a tone step with ink text */
.seg.is-fill {
  display: flex;
  width: 100%;
  height: var(--control-xl);
  padding: 3px;
  gap: 2px;
  background: var(--ground);
  box-shadow: inset 0 0 0 1px var(--panel-line);
}

.seg.is-fill > button {
  flex: 1 1 0;
  min-width: 0;
  gap: var(--s-1);
  font-size: var(--type-body);
}

.seg > [aria-checked="true"],
.seg > [aria-selected="true"] {
  --ink: var(--text-strong);
  background: var(--raised-active);
  font-weight: 600;
}

/* Estimate: label over figure in one joined strip; before a pattern exists, one line instead */
.estimate-empty {
  padding: var(--s-4);
  border-radius: var(--radius-control);
  background: var(--ground);
  color: var(--text-dim);
}

.figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border-radius: var(--radius-control);
  background: var(--panel-line);
}

@media (min-width: 560px) {
  .figures { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.figures > div {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-1);
  min-width: 0;
  padding: var(--s-3);
  background: var(--ground);
}

.figures dd,
.budget dd,
.job-stats dd {
  color: var(--text-strong);
  font-family: var(--font-mono);
  font-size: var(--type-reading);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-tight);
  overflow-wrap: anywhere;
  border-radius: 0.25rem;
  transition: background-color var(--duration-base) var(--ease-out);
}

.flash { background: var(--raised-active); }

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }

.btn-xl {
  --btn-h: var(--control-xl);
  padding: 0 var(--s-5);
  font-size: var(--type-body);
}

/* The one ink element: a 1px inset highlight and one sheen on hover (finish, not glow) */
.btn-primary { overflow: hidden; }
.btn-primary:not(:disabled) { box-shadow: inset 0 1px 0 #ffffff66; }

.btn-primary:not(:is(.is-loading, [aria-busy="true"]))::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, #ffffff99 50%, transparent 70%);
  transform: translateX(-120%);
  pointer-events: none;
}

@media (hover: hover) {
  .btn-primary:not(:disabled):hover::after {
    transform: translateX(120%);
    transition: transform var(--duration-long) var(--ease-out);
  }
}

.action-note { color: var(--text-dim); font-size: var(--type-small); }

@media (max-width: 479px) {
  .actions > .btn { width: 100%; }
}

.reason {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  color: var(--text-body);
  font-size: var(--type-small);
  overflow-wrap: anywhere;
}

.reason .dot { margin-top: 0.3rem; color: var(--tone, var(--warning)); }

/* Live card: the job you just started, under the composer */
.live-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4) var(--s-4);
  border-radius: var(--radius-control);
  background: var(--ground);
}

.live-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.live-card .job { padding: var(--s-2) 0 0; }

/* ---------------------------------------------------------------- Jobs */
.signed-out {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-6) var(--s-4);
  color: var(--text-dim);
  text-align: center;
}

.budget {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4) var(--s-3);
  padding: var(--s-4);
}

.budget .is-key { grid-column: 1 / -1; }

@media (min-width: 560px) {
  .budget { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); padding: var(--s-5); }
  .budget .is-key { grid-column: auto; }
}

.budget > div { display: flex; flex-direction: column; justify-content: flex-end; gap: var(--s-1); min-width: 0; }

.budget .is-key dd,
.job-stats .is-key dd {
  font-size: var(--type-title);
  line-height: 1;
  letter-spacing: -0.01em;
}

.job-list { display: flex; flex-direction: column; padding: 0; margin: 0; list-style: none; }

.job { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-4); }
.job + .job { border-top: 1px solid var(--line-row); }

@media (min-width: 640px) {
  .job { padding: var(--s-4) var(--s-5); }
}

.job-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-2) var(--s-3);
}

.job-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-1) var(--s-2); min-width: 0; }

.job-pattern {
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--type-reading);
  overflow-wrap: anywhere;
}

.job-pattern .pat { color: var(--text-strong); font-weight: 650; }

.job-meta { color: var(--text-dim); font-size: var(--type-small); font-variant-numeric: tabular-nums; white-space: nowrap; }

.chip { align-self: center; }

.job .live { font-size: var(--type-small); }
.live > .dot { color: var(--tone, var(--positive)); }

.job-stats {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
  gap: var(--s-3);
  align-items: start;
}

@media (max-width: 479px) {
  .job-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .job-stats .is-key { grid-column: 1 / -1; }
}

.job-stats > div { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.job-stats dd { font-size: var(--type-body); }

.unlucky { color: var(--text-dim); font-size: var(--type-small); }

.progress { --tone: var(--text-strong); }
.progress > i { transition: width var(--duration-base) var(--ease-out); }
.progress.is-booting > i { width: 30%; animation: booting 1.2s var(--ease-in-out) infinite alternate; }

@keyframes booting {
  from { transform: translateX(-30%); }
  to { transform: translateX(260%); }
}

.job-error {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  color: var(--text-body);
  font-size: var(--type-small);
  overflow-wrap: anywhere;
}

.job-error .dot { margin-top: 0.3rem; color: var(--negative); }

/* Results: one line per address with its actions, one save line, keys under their address */
.results summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: fit-content;
  min-height: var(--control-md);
  color: var(--text-body);
  font-size: var(--type-small);
  cursor: pointer;
  list-style: none;
}

.results summary::-webkit-details-marker { display: none; }

.results summary::before {
  content: "";
  width: 0.375rem;
  height: 0.375rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--duration-fast) var(--ease-out);
}

.results[open] summary::before { transform: rotate(45deg); }
.results summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 0.25rem; }
.results-body { display: flex; flex-direction: column; gap: var(--s-3); padding-top: var(--s-2); }

/* Key row: the address (and a dim meta line) on the left, one joined action group on the right.
   Same row in a job's results and on the Addresses tab. */
.key-list { display: flex; flex-direction: column; padding: 0; margin: 0; list-style: none; }

.key-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  min-width: 0;
}

.key-list > .key-row + .key-row { padding-top: var(--s-3); margin-top: var(--s-3); border-top: 1px solid var(--line-row); }

.key-main { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.key-meta { color: var(--text-dim); font-size: var(--type-small); }

/* The group is a well like the segmented controls: 1px line, small inset, buttons step up a tone on hover */
.key-actions {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line-row);
  border-radius: var(--radius-control);
  background: var(--ground);
}

.key-btn {
  display: inline-grid;
  place-items: center;
  height: var(--control-md);
  padding: 0 var(--s-3);
  border: 0;
  border-radius: calc(var(--radius-control) - 2px);
  background: transparent;
  color: var(--text-body);
  font: inherit;
  font-size: var(--type-small);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}

.key-btn > span { grid-area: 1 / 1; transition: opacity var(--duration-fast) var(--ease-out); }
.key-btn > .done,
.key-btn > .armed { opacity: 0; }
.key-btn[data-copied] > .idle,
.key-btn[data-armed] > .idle { opacity: 0; }
.key-btn[data-copied] > .done,
.key-btn[data-armed] > .armed { opacity: 1; }
.key-btn[data-copied] { color: var(--text-strong); }

@media (hover: hover) {
  .key-btn:hover { background: var(--raised); color: var(--text-strong); }
  .key-btn.is-danger:hover { color: var(--negative); }
}

.key-btn:active { background: var(--raised-active); }
.key-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.key-btn:disabled { color: var(--text-dim); cursor: default; }
.key-btn[aria-busy="true"] { cursor: progress; color: var(--text-dim); }
.key-btn.is-danger { color: var(--text-dim); }
.key-btn.is-danger[data-armed] { background: color-mix(in oklab, var(--negative) 16%, transparent); color: var(--negative); }

/* Addresses tab rows sit in the panel's own padding */
#addr-history > .key-row { padding: var(--s-3) var(--s-4); }
#addr-history > .key-row + .key-row { border-top: 1px solid var(--line-row); }

@media (min-width: 640px) {
  #addr-history > .key-row { padding: var(--s-3) var(--s-5); }
}

/* Phones: the group drops under the address and spreads full width, with touch-sized targets */
@media (max-width: 639px) {
  .key-row { grid-template-columns: minmax(0, 1fr); }
  .key-actions { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
}

@media (pointer: coarse) {
  .key-btn { height: 2.75rem; }
}

.job-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }

.more { align-self: center; }

.empty-line { padding: var(--s-6) var(--s-4); color: var(--text-dim); text-align: center; }

/* Copy word: reserves the wider of its two labels, confirms in a word */
.copy-word { display: inline-grid; }
.copy-word > span { grid-area: 1 / 1; transition: opacity var(--duration-fast) var(--ease-out); }
.copy-word > .done { opacity: 0; }
.copy-word[data-copied] > .idle { opacity: 0; }
.copy-word[data-copied] > .done { opacity: 1; }

/* ---------------------------------------------------------------- Sign-in dialog */
.dialog { border: 1px solid var(--panel-line); }
body:has(dialog[open]) { overflow: hidden; }
.dialog-body { display: flex; flex-direction: column; gap: var(--s-4); }
.dialog-body > p { color: var(--text-dim); }

/* ---------------------------------------------------------------- States */
@media (hover: none) {
  .btn:hover { background: var(--btn-bg); }
  .seg > button:hover { --ink: var(--text-dim); }
  .seg > [aria-checked="true"]:hover,
  .seg > [aria-selected="true"]:hover { --ink: var(--text-strong); }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .view { animation: none; }
  .progress.is-booting > i { animation: none; transform: none; width: 100%; opacity: 0.4; }
  .btn-primary::after { display: none; }
}

/* Narrow phones: the three view tabs keep their counts without touching the edge */
@media (max-width: 399px) {
  .views-seg > button { padding: 0 var(--s-1); font-size: var(--type-small); }
}

@media (max-width: 379px) {
  .chars-left { display: none; }
}

/* ---------------------------------------------------------------- App shell: the page never scrolls.
   Top bar and view switch stay put; the Grind view scrolls on its own when a phone is too short,
   and the Jobs and Addresses lists scroll inside their panels. */
html, body { height: 100%; }

body {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
}

.topbar { flex: none; }

main.wrap {
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: var(--s-4);
}

.views { position: static; flex: none; margin: 0; padding: 0; }

.view {
  flex: 1 1 auto;
  min-height: 0;
}

.view.is-scroll {
  overflow-y: auto;
  scrollbar-gutter: stable;
  overscroll-behavior: contain;
  padding-bottom: var(--s-4);
}

.fill {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.scroll-panel {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-gutter: stable;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--raised-active) transparent;
}

.view.is-scroll { scrollbar-width: thin; scrollbar-color: var(--raised-active) transparent; }

.has-more {
  mask-image: linear-gradient(to bottom, #000 calc(100% - 2.5rem), transparent);
}

/* The Grind view reserves no scrollbar gutter, so its panel edges line up with the view switch */
.view.is-scroll { scrollbar-gutter: auto; }


/* ---------------------------------------------------------------- Calm job rows (2026-11-08: "better on the eyes")
   One bright thing per row at most: the matched part of the address. Words over mono bold, no inner wells,
   quiet text buttons, status and meta dim. */
.job { gap: var(--s-2); }
.job-top { align-items: baseline; }
.job-title { align-items: baseline; gap: var(--s-1) var(--s-3); }

.job-words { color: var(--text-dim); font-size: var(--type-body); }
.job-pat { color: var(--text-body); font-family: var(--font-mono); font-weight: 500; }
.job-meta { color: var(--text-dim); }

.job .live { color: var(--text-dim); font-size: var(--type-small); }
.job .live > .dot { width: 0.375rem; height: 0.375rem; }

.address.is-small { color: var(--text-dim); font-size: 0.9375rem; }
.address.is-small .pat { color: var(--text-strong); font-weight: 500; }

.job-actions .btn {
  --ink: var(--text-dim);
}

@media (hover: hover) {
  .job-actions .btn:hover { --ink: var(--text-strong); }
}

.job-actions { gap: var(--s-1) var(--s-3); }
.job-actions .btn { padding-inline: 0; height: 1.75rem; }
.job-actions .copy-word > span { justify-self: start; }
.job-actions .btn:hover { background: none; text-decoration: underline; text-underline-offset: 3px; }
.results-body { gap: var(--s-2); padding-top: var(--s-1); }

/* List panels hug their content and only scroll once they reach the bottom of the view */
.scroll-panel { flex: 0 1 auto; }

.job-pat,
.address.is-small .pat { font-weight: 450; }
.scroll-panel { scrollbar-gutter: auto; }

/* ---------------------------------------------------------------- Polish 2026-11-09 ("more professional and legit")
   One name (vanity wordmark), tabs in the header as product chrome, a short lede, a sourced trust strip,
   sentence-case field labels, and a flat Start button with no sheen. */

/* Header: wordmark | tabs | account on one row from 640; two rows on phones */
.topbar { height: auto; }

.topbar .wrap {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "mark tabs account";
  align-items: center;
  gap: var(--s-2) var(--s-6);
  height: auto;
  min-height: 3.5rem;
}

.wordmark {
  grid-area: mark;
  display: inline-flex;
  align-items: center;
  min-height: var(--hit);
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  text-decoration: none;
}

.wordmark:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 0.25rem; }

.topbar .views { grid-area: tabs; }
.topbar .account-nav { grid-area: account; justify-self: end; }

@media (min-width: 640px) {
  /* Plain tabs: the active one in strong text over a 2px lime rule */
  .topbar .views-seg {
    width: auto;
    height: 3.5rem;
    padding: 0;
    gap: var(--s-5);
    background: none;
    box-shadow: none;
  }

  .topbar .views-seg > button {
    flex: none;
    padding: 0;
    border-radius: 0;
    background: none;
    font-size: var(--type-body);
  }

  .topbar .views-seg > [aria-selected="true"] {
    background: none;
    box-shadow: inset 0 -2px 0 var(--accent);
  }

  .topbar .views-seg > button:active { transform: none; }
}

@media (max-width: 639px) {
  .topbar .wrap {
    grid-template-columns: 1fr auto;
    grid-template-areas: "mark account" "tabs tabs";
    padding-bottom: var(--s-3);
  }
}

main.wrap { padding-top: var(--s-6); }

/* Lede: one sentence at reading size */
.intro p { font-size: 1.125rem; line-height: 1.5; color: var(--text-body); }

/* Field labels in sentence case; figure captions keep the system's uppercase */
.field-label {
  color: var(--text-body);
  font-size: var(--type-small);
  letter-spacing: 0;
  text-transform: none;
}

/* Start: a flat lime fill, no sheen, no highlight */
.btn-primary:not(:disabled) { box-shadow: none; }
.btn-primary::after { content: none; }

/* ---------------------------------------------------------------- Controls (owner 2026-11-09: "these inputs and toggles look tacky")
   Cause: every control was a stock outlined box of equal weight, the chosen segment was just another grey,
   and focus drew a double ring, so the panel read as an admin form.
   Segments: Osmo "Toggle Switch" pattern (osmo-vault toggle-switch), ported to CSS: one thumb slides under
   the chosen option, positioned from the aria state app.js already sets. Inputs: taller mono fields with a
   lime caret and a single crisp focus edge. */

.seg.is-fill {
  --n: 2;
  --i: 0;
  --inset: 3px;
  position: relative;
  isolation: isolate;
  height: 3rem;
  padding: var(--inset);
  gap: 0;
  border-radius: 0.75rem;
  box-shadow: inset 0 0 0 1px var(--panel-line);
}

#count,
#views { --n: 3; }

.seg.is-fill:has(> :nth-child(2):is([aria-checked="true"], [aria-selected="true"])) { --i: 1; }
.seg.is-fill:has(> :nth-child(3):is([aria-checked="true"], [aria-selected="true"])) { --i: 2; }

.seg.is-fill::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: var(--inset);
  bottom: var(--inset);
  left: var(--inset);
  width: calc((100% - 2 * var(--inset)) / var(--n));
  border-radius: calc(0.75rem - var(--inset));
  background: var(--raised-active);
  box-shadow: inset 0 1px 0 #ffffff14;
  transform: translateX(calc(var(--i) * 100%));
  transition: transform 450ms cubic-bezier(0.625, 0.05, 0, 1);
}

.seg.is-fill > button,
.seg.is-fill > [aria-checked="true"],
.seg.is-fill > [aria-selected="true"] {
  background: transparent;
  border-radius: calc(0.75rem - var(--inset));
  transition: color 180ms var(--ease-out);
}

.seg.is-fill > button:active { transform: none; }

/* Inputs: one height with the segments, mono text, lime caret, a single 2px lime edge on focus */
.composer .input {
  height: 3rem;
  padding: 0 var(--s-4);
  border-radius: 0.75rem;
  font-size: var(--type-reading);
  caret-color: var(--accent);
}

.composer .input:focus-visible {
  border-color: var(--accent);
  outline: none;
  box-shadow: inset 0 0 0 1px var(--accent);
}

.composer .input::placeholder { color: var(--text-dim); }

/* Estimate and preview wells: same radius as the controls */
.preview,
.estimate-empty,
.figures { border-radius: 0.75rem; }

@media (prefers-reduced-motion: reduce) {
  .seg.is-fill::before { transition: none; }
}

/* Header tabs from 640 stay plain tabs (wordmark row), not a sliding well */
@media (min-width: 640px) {
  .topbar .views-seg.is-fill {
    height: 3.5rem;
    padding: 0;
    gap: var(--s-5);
    border-radius: 0;
    box-shadow: none;
  }

  .topbar .views-seg.is-fill::before { content: none; }

  .topbar .views-seg.is-fill > [aria-selected="true"] {
    border-radius: 0;
    box-shadow: inset 0 -2px 0 var(--accent);
  }
}

/* ---------------------------------------------------------------- Running job (owner 2026-11-09: "expands really aggressivly",
   "the cancle button looks really bad", the blue Grinding marker and the amber square on the warning line)
   Cause: the Jobs-tab row was dropped into the composer whole (36px figure, uppercase stats, a padding-less grey
   pill for Cancel, the kit's square markers in off-palette blue and amber) and it appeared with no transition. */

/* Live state is the accent (one of its four roles); markers are small round dots everywhere */
:root { --info: var(--accent); }

.dot {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 999px;
}

.dot.is-live::after { animation-duration: 1.6s; }

.reason .dot,
.job-error .dot,
.field-error .dot,
.field-note .dot { margin-top: 0.45rem; }

/* The live card eases open instead of popping in */
.live-card {
  gap: var(--s-3);
  padding: var(--s-4);
  border-radius: 0.75rem;
  overflow: clip;
  interpolate-size: allow-keywords;
  transition: height 250ms var(--ease-out), opacity 250ms var(--ease-out);
}

@starting-style {
  .live-card { height: 0; opacity: 0; }
}

.live-card-head .label {
  font-size: var(--type-small);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-body);
}

.live-card .job { padding: 0; gap: var(--s-3); }

/* Compact stats in the live card: the chance figure leads at figure size, the rest sit beside it */
.live-card .job-stats { gap: var(--s-2) var(--s-4); }
.live-card .job-stats dt { font-size: var(--type-label); }
.live-card .job-stats .is-key dd { font-size: var(--type-figure); }

/* Progress: a thin lime rule */
.progress { --tone: var(--accent); height: 3px; }

/* Cancel: a real small secondary button, not a squeezed pill */
.job-actions > .btn-secondary {
  height: 2rem;
  padding: 0 var(--s-3);
  border-radius: 0.5rem;
  background: var(--raised);
  color: var(--text-body);
  text-decoration: none;
}

@media (hover: hover) {
  .job-actions > .btn-secondary:hover {
    background: var(--raised-hover);
    color: var(--text-strong);
    text-decoration: none;
  }
}

@media (pointer: coarse) {
  .job-actions > .btn-secondary { height: 2.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .live-card { transition: none; }
}

/* The Grind view scrolls on short screens; its blocks keep their natural height and no scrollbar shows
   (owner, 2026-11-09: "remove the side bar") */
#view-grind > * { flex: none; }
html { scrollbar-gutter: auto; }
.view.is-scroll { scrollbar-width: none; }
.view.is-scroll::-webkit-scrollbar { display: none; }

/* Empty and signed-out states read at body size */
.signed-out p,
.empty-line { font-size: var(--type-reading); }
