/* Receiving terminal.
 *
 * Hand-written rather than Tailwind, deliberately. The terminal is a small
 * closed set of screens with an unusual brief — read at arm's length, operated
 * with gloves — so a utility framework would mostly be fought rather than used,
 * and it would add a build step to a project maintained by one person. Tailwind
 * arrives when the back office grows enough screens to earn it.
 *
 * Tokens are the ones agreed in the design study. Colour is never the only
 * signal: every state carries a word or a shape as well as a hue.
 */

:root {
  color-scheme: dark;
  --ground: #0d1214;
  --surface: #161f23;
  --surface-2: #1f2a2f;
  --line: #2c3a40;
  --ink: #eaf2f4;
  --muted: #93a6ad;
  --accent: #ff7a18;
  --accent-ink: #1a0d03;
  --ok: #34d399;
  --info: #38bdf8;
  --stop: #f43f5e;

  --sans: "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", "Roboto Mono", Consolas, monospace;

  /* Minimum comfortable target for a gloved hand. Nothing tappable goes below. */
  --tap: 56px;
}

/* Dark is the default a kiosk boots into. Light is an explicit per-device
 * choice (see the toggle in the topbar) for stations set up somewhere glare
 * makes dark hard to read, and it is remembered on that terminal, not tied
 * to whoever is scanning. */
:root[data-theme="light"] {
  color-scheme: light;
  --ground: #eef1f2;
  --surface: #ffffff;
  --surface-2: #f1f4f5;
  --line: #d7dee1;
  --ink: #10181b;
  --muted: #55656a;
  --accent: #c74e00;
  --accent-ink: #fff8f0;
  --ok: #0f8a56;
  --info: #0369a1;
  --stop: #c81e3a;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Stops iOS/Android double-tap zoom on the shop floor. */
  touch-action: manipulation;
}

.shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  max-width: 1100px;
  margin: 0 auto;
}

/* ---------- chrome ---------- */

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  position: sticky;
  top: 0;
  z-index: 5;
}

.topbar a { color: inherit; text-decoration: none; }
.topbar-doc { color: var(--ink); font-weight: 600; }
.topbar-meta { display: flex; gap: 14px; align-items: center; }

.theme-toggle {
  min-width: var(--tap);
  min-height: var(--tap);
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: 0;
}
.theme-toggle:hover { background: var(--line); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-toggle .icon-dark { display: none; }
:root[data-theme="light"] .theme-toggle .icon-light { display: none; }
:root[data-theme="light"] .theme-toggle .icon-dark { display: inline; }

.body {
  flex: 1;
  padding: 26px 22px;
  display: flex;
  flex-direction: column;
}

.footbar {
  border-top: 1px solid var(--line);
  background: var(--surface);
  padding: 11px 18px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* ---------- headings ---------- */

.prompt { font-size: 15px; color: var(--muted); margin: 0 0 6px; }

.headline {
  font-size: 34px;
  line-height: 1.06;
  letter-spacing: -0.02em;
  font-weight: 650;
  margin: 0;
  text-wrap: balance;
}

.section-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 26px 0 10px;
}

/* ---------- scan field ----------
 * The input is real and always focused, because a keyboard-wedge scanner is
 * just a very fast typist. Making it invisible would break autofill hints and
 * phone keyboards, so it is styled instead of hidden. */

.scanbox {
  border: 2px dashed var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  padding: 16px 18px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.scanbox .beam {
  width: 4px;
  align-self: stretch;
  min-height: 34px;
  background: var(--accent);
  animation: pulse 1.5s ease-in-out infinite;
  flex: none;
}

@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: 0.25 } }

@media (prefers-reduced-motion: reduce) {
  .scanbox .beam, .dot { animation: none; }
}

.scanbox input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 19px;
  min-height: 40px;
}

.scanbox input::placeholder { color: var(--muted); }
.scanbox-hint {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.05em;
  margin-top: 4px;
}

/* ---------- lists ---------- */

.rule-divider {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 20px 0 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.rule-divider::before, .rule-divider::after {
  content: "";
  height: 1px;
  background: var(--line);
  flex: 1;
}

.rows {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-top: 16px;
}

.row {
  background: var(--surface);
  border: 0;
  border-left: 3px solid transparent;
  color: var(--ink);
  font-family: var(--sans);
  text-align: left;
  width: 100%;
  min-height: var(--tap);
  padding: 12px 15px;
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
}

.row:hover { background: var(--surface-2); border-left-color: var(--accent); }
.row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.row[data-state="confirmed"] { border-left-color: var(--ok); }
.row[aria-disabled="true"] { cursor: default; opacity: 0.75; }
.row[aria-disabled="true"]:hover { background: var(--surface); border-left-color: var(--ok); }

.row-name { font-size: 15px; font-weight: 500; }
.row-sub {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
}
.row-qty {
  font-family: var(--mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}

@media (max-width: 520px) {
  .row { grid-template-columns: 1fr auto; }
  .row-qty { grid-column: 1; font-size: 12px; }
  .headline { font-size: 25px; }
  .body { padding: 18px 15px; }
}

/* ---------- chips ---------- */

.chip {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 8px;
  border: 1px solid currentColor;
  white-space: nowrap;
}
.chip.ok { color: var(--ok); }
.chip.wait { color: var(--muted); }
.chip.info { color: var(--info); }
.chip.stop { color: var(--stop); }

/* ---------- matched item ---------- */

.card {
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 20px;
  margin-top: 18px;
}

.card-top {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.card-name { font-size: 20px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.card-sub { font-family: var(--mono); font-size: 12px; color: var(--muted); margin: 5px 0 0; }

.figure { text-align: right; font-family: var(--mono); }
.figure-n { font-size: 30px; font-variant-numeric: tabular-nums; display: block; line-height: 1; }
.figure-l {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- forms ---------- */

.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 20px; }
@media (max-width: 620px) { .fields { grid-template-columns: 1fr; } }

.field label {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 7px;
}

.field input, .field select {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface-2);
  padding: 12px 14px;
  font-family: var(--mono);
  font-size: 18px;
  color: var(--ink);
  min-height: var(--tap);
  font-variant-numeric: tabular-nums;
  border-radius: 0;
}

.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.field-note { font-size: 12px; color: var(--muted); margin: 6px 0 0; }

.actions { display: flex; gap: 12px; margin-top: 22px; flex-wrap: wrap; }

.btn {
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 600;
  padding: 0 22px;
  min-height: var(--tap);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
  flex: 1;
  min-width: 130px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  border-radius: 0;
}

.btn:hover { background: var(--line); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn.primary:hover { filter: brightness(1.08); }
.btn.quiet { flex: 0 0 auto; min-width: 0; padding: 0 16px; font-weight: 500; }

/* ---------- alarms and confirmations ---------- */

.alarm {
  border: 2px solid var(--stop);
  background: color-mix(in srgb, var(--stop) 12%, transparent);
  padding: 22px;
  margin-top: 18px;
}
.alarm-tag {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stop);
  margin: 0 0 10px;
}
.alarm h2 { font-size: 24px; margin: 0 0 9px; font-weight: 650; letter-spacing: -0.01em; text-wrap: balance; }
.alarm p { margin: 0; color: var(--muted); font-size: 14px; }
.alarm code, .done code { font-family: var(--mono); color: var(--ink); }

.done {
  border: 1px solid var(--ok);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  padding: 20px;
  margin-top: 18px;
}
.done-tag {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ok);
  margin: 0 0 10px;
}
.done-code { font-family: var(--mono); font-size: 28px; margin: 0 0 6px; letter-spacing: -0.01em; }
.done-sub { margin: 0; color: var(--muted); font-size: 14px; }

.notice {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 12px 15px;
  border: 1px solid var(--line);
  background: var(--surface);
  font-family: var(--mono);
  font-size: 13px;
}
.notice .dot {
  width: 8px;
  height: 8px;
  background: var(--info);
  flex: none;
  animation: pulse 1.1s ease-in-out infinite;
}
.notice.warn { border-color: var(--info); }

/* ---------- progress ---------- */

.progress { margin-top: auto; padding-top: 24px; }
.progress-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.progress-count { color: var(--ink); font-size: 15px; font-variant-numeric: tabular-nums; }
.bar { height: 8px; background: var(--surface-2); border: 1px solid var(--line); display: flex; }
.bar span { background: var(--ok); display: block; }

.empty { color: var(--muted); font-size: 15px; margin: 18px 0 0; }

/* ---------- operator code keypad ----------
 * Rendered rather than relying on the Android soft keyboard, which is small,
 * carries letters and covers half the screen. Keys are deliberately large:
 * gloved hands at gluing and cutting have no precision, and a key that needs
 * aiming is a key that gets mis-hit and then re-typed. */

.keypad { margin-top: 8px; max-width: 340px; }

.keypad-label {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 7px;
}

.keypad-display {
  width: 100%;
  border: 2px solid var(--accent);
  background: var(--surface-2);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 30px;
  letter-spacing: 0.28em;
  text-align: center;
  min-height: 64px;
  padding: 6px 10px;
  border-radius: 0;
}

.keypad-display::placeholder { color: var(--line); letter-spacing: 0.28em; }
.keypad-display:focus { outline: none; }

.keypad-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 8px;
}

.keypad-key {
  min-height: 70px;
  font-family: var(--mono);
  font-size: 26px;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--line);
  cursor: pointer;
  border-radius: 0;
  /* Stops a fast double-tap being read as a zoom gesture mid-entry. */
  touch-action: manipulation;
  user-select: none;
}

.keypad-key:active { background: var(--accent); color: var(--accent-ink); }
.keypad-key:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.keypad-wide { font-size: 15px; }

@media (max-width: 520px) {
  .keypad { max-width: 100%; }
  .keypad-key { min-height: 62px; font-size: 23px; }
}

/* Visible to screen readers only. Scan fields carry a real label even though
 * the placeholder reads as one visually. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* A row rendered as a submit button inherits none of the layout, so restate it. */
form > .row { width: 100%; }
.rows > form { display: contents; }

/* HTMX: dim the region being replaced so a slow network reads as busy
 * rather than broken. */
.htmx-request .body { opacity: 0.55; transition: opacity 0.1s; }

/* --- production board ---------------------------------------------------
   One row, up to four sections. Panels are tall and narrow rather than wide,
   because the queue reads down. Below 900px they wrap rather than shrink —
   an unreadable panel is worse than a scroll. */
.board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px;
  margin-top: 18px;
}
.board-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 260px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 3px solid var(--line);
  color: inherit;
  text-decoration: none;
}
.board-panel:hover { background: var(--surface-2); }
.board-panel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.board-panel[data-state="running"] { border-top-color: var(--ok); }
.board-panel[data-state="needs_material"] { border-top-color: var(--stop); }
.board-panel[data-state="waiting"] { border-top-color: var(--info); }

.board-section {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.board-state { font-size: 12px; color: var(--muted); }
.board-panel[data-state="needs_material"] .board-state { color: var(--stop); font-weight: 600; }
.board-panel[data-state="running"] .board-state { color: var(--ok); }

.board-queue { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.board-job {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--mono);
  font-size: 12px;
}
.board-job-qty { color: var(--muted); font-variant-numeric: tabular-nums; }
.board-more, .board-empty { font-size: 12px; color: var(--muted); }

.board-ask, .board-short {
  margin-top: auto;
  font-size: 12px;
  line-height: 1.4;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.board-ask { color: var(--stop); font-weight: 600; }
.board-ask-age { font-family: var(--mono); font-weight: 400; }
.board-short { color: var(--muted); }

.fold { margin-top: 20px; border-top: 1px solid var(--line); }
.fold > summary {
  cursor: pointer;
  padding: 14px 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.fold > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fold[open] > summary { color: var(--ink); }

/* === Office screens: forms and detail pages (accounts, warranty) ============
   Everything above is for kiosks and is left alone. These rules only add:
   a reading-width column, textareas, inline field errors, and the layout of a
   record page. Nothing here changes how an existing class looks. */

.page { width: 100%; max-width: 720px; margin: 0 auto; }

.field textarea {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface-2);
  padding: 12px 14px;
  font-family: var(--mono);
  /* 16px or more, or iOS zooms the page when the field is focused. */
  font-size: 18px;
  line-height: 1.4;
  color: var(--ink);
  min-height: 112px;
  resize: vertical;
  border-radius: 0;
}
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.field.wide { grid-column: 1 / -1; }
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--stop); }

/* Words as well as colour: the text starts "Error:" in the markup. */
.field-error { font-size: 13px; font-weight: 600; color: var(--stop); margin: 6px 0 0; }

.fields.one { grid-template-columns: 1fr; }
.item.has-error { border-color: var(--stop); }
.btn.danger { border-color: var(--stop); color: var(--stop); }
.alarm p.lead, .done p.lead { color: var(--ink); font-size: 15px; }
.page .prompt a { color: inherit; }

.alarm ul { margin: 0; padding-left: 18px; color: var(--muted); font-size: 14px; }
.alarm li + li { margin-top: 4px; }

/* One line of goods on the form. */
.item {
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 4px 16px 16px;
  margin: 14px 0 0;
  min-width: 0;
}
.item legend {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0 6px;
}
.item .fields { margin-top: 10px; }
.item-foot { display: flex; justify-content: flex-end; margin-top: 12px; }
.item-foot .btn { min-height: 44px; }
.btn.small { min-height: 44px; }

/* The save bar stays at the bottom of the screen on a phone, so the primary
   action is under the thumb however long the form is. */
.form-bar {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  gap: 12px;
  margin: 26px -22px 0;
  padding: 12px 22px;
  background: var(--ground);
  border-top: 1px solid var(--line);
}
.form-bar .btn { margin: 0; }
@media (max-width: 520px) {
  .form-bar { margin-left: -15px; margin-right: -15px; padding-left: 15px; padding-right: 15px; }
}

/* A record page: label above value, two columns when there is room. */
.facts { display: grid; grid-template-columns: 1fr; gap: 14px 24px; margin: 0; }
.facts dt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 3px;
}
.facts dd { margin: 0; font-size: 16px; overflow-wrap: anywhere; }
.facts .wide { grid-column: 1 / -1; }
.facts .address { white-space: pre-line; }
@media (min-width: 620px) { .facts { grid-template-columns: 1fr 1fr; } }

/* Rows that show a record rather than link to one. */
.row.static { cursor: default; }
.row.static:hover { background: var(--surface); border-left-color: transparent; }
.row-sub.problem { color: var(--stop); white-space: normal; overflow-wrap: anywhere; }

.notice.block { align-items: flex-start; font-family: var(--sans); font-size: 14px; }
.notice.block .chip { margin-top: 2px; }

.signed-in {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 30px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--muted);
}
.signed-in form { margin: 0; }

/* Wide screens: buttons keep a sensible size instead of stretching across. */
@media (min-width: 760px) {
  .page .actions > .btn,
  .page .actions > form > .btn { flex: 0 0 auto; min-width: 200px; }
  .page .actions > .btn.quiet { min-width: 0; }
  .form-bar { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
  .form-bar .btn { flex: 0 0 auto; min-width: 200px; }
  .form-bar .btn.quiet { min-width: 0; }
}

/* Long text that has no place to break (an email address, a provider's error
   message, a surname typed without spaces) must wrap instead of pushing the
   page wider than a 390px phone. `anywhere` rather than `break-word`: it also
   shrinks the text's minimum width, which flex and grid items need before they
   are allowed to get narrower than their content. */
.page .alarm p,
.page .done p,
.page .notice.block > span,
.page .field-note,
.page .field-error,
.page strong,
.page .row-name,
.page .row-sub { overflow-wrap: anywhere; }
.page .row-name,
.page .notice.block > span { min-width: 0; }
/* ...but not the chip beside it: the rule above also lets the chip shrink, and
   on a phone it shrank to nothing and the sentence ran over the top of it. */
.page .notice.block > .chip { flex: 0 0 auto; white-space: nowrap; overflow-wrap: normal; }
/* In a list row the chip is a label, not a bar: on a phone the row stacks and
   the chip would otherwise stretch to the full width. */
.page .row.static > .chip { justify-self: start; }

/* The WhatsApp button: Fern from the brand palette, so it reads as "the green
   one" without borrowing another company's exact colour. */
.btn.whatsapp { border-color: #14AD88; box-shadow: inset 4px 0 0 #14AD88; }
.btn.whatsapp:hover { background: var(--line); }

/* === Home screen: one card per part of the system =========================
   Each module has a colour from the brand palette, so a card is found by
   colour as well as by name, and stays the same colour when the full ERP adds
   its neighbours. --tone-ink is the icon's colour on that tone, chosen for
   contrast: dark on the light tones, white on the two deep ones. */
.home { width: 100%; max-width: 980px; margin: 0 auto; }
.home .headline { margin-bottom: 4px; }
.modules {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
  margin-top: 24px;
}
.module {
  --tone: #CDBEAF;
  --tone-ink: #3A4C5C;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 176px;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 4px solid var(--tone);
  color: var(--ink);
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
.module:hover { background: var(--surface-2); border-color: var(--tone); transform: translateY(-2px); }
.module:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.module-icon {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 16px;
  background: var(--tone);
  color: var(--tone-ink);
}
.module-icon svg {
  width: 30px;
  height: 30px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.module-text { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.module-title { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.module-blurb { font-size: 14px; line-height: 1.45; color: var(--muted); }
.module-badge {
  position: absolute;
  top: 18px;
  right: 18px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--tone);
  color: var(--tone-ink);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.tone-sunrise  { --tone: #E9B81B; }
.tone-tranquil { --tone: #78BDDA; }
.tone-cozy     { --tone: #EB9147; }
.tone-lush     { --tone: #EEB3B4; }
.tone-linen    { --tone: #CDBEAF; }
.tone-fern     { --tone: #14AD88; --tone-ink: #ffffff; }
.tone-plum     { --tone: #7D3B6E; --tone-ink: #ffffff; }
.home-out { margin-top: 28px; }

/* On a phone a card is a row: the icon, then the words. Six tall cards would
   be a long scroll for what is a short list. */
@media (max-width: 560px) {
  .modules { grid-template-columns: 1fr; gap: 10px; }
  .module {
    flex-direction: row;
    align-items: center;
    min-height: 0;
    padding: 14px 16px;
    border-top-width: 1px;
    border-left: 4px solid var(--tone);
  }
  .module:hover { transform: none; }
  .module-icon { width: 48px; height: 48px; border-radius: 14px; }
  .module-icon svg { width: 26px; height: 26px; }
  .module-badge { position: static; margin-left: auto; align-self: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
  .module { transition: none; }
  .module:hover { transform: none; }
}
