/* ============================================================
   Longtom — the stable stylesheet.
   Brand: Longtom brand.jpg · Rules: DESIGN.md
   Tokens + component primitives. Pages compose these;
   nothing user-facing hardcodes a colour or a font.
   ============================================================ */

/* ---- Type ---------------------------------------------------------------- */
@font-face {
  font-family: "Poppins";
  src: url("/fonts/Poppins-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/fonts/Poppins-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/Inter-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/Inter-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/Inter-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

/* ---- Tokens: light (default) ---------------------------------------------
   Two families on purpose. The *-ink colours are for TEXT and clear 4.5:1
   against every surface they land on; the brand colours stay exactly as drawn
   and are used for fills — the logo, a button, the rail beside the active
   nav item. Identity survives; small type stays readable. Measured, not
   guessed: --ink-3 at the old #8AA0AC was 2.73:1, which is not a colour, it is
   a suggestion of one.                                                      */
:root {
  --lt-blue: #0A86C2;
  --lt-blue-ink: #0873A6;
  --lt-blue-deep: #0A6DA0;
  --lt-blue-wash: #E3F1F9;
  --lt-teal: #00B4D8;
  --lt-teal-ink: #007890;
  --lt-teal-wash: #E0F6FA;
  --lt-gold: #FF9F1C;
  --lt-gold-ink: #9E6211;
  --lt-gold-wash: #FFF2DE;

  --bg: #F3F7FA;
  --surface: #FFFFFF;
  --surface-2: #EAF1F6;
  --ink: #263238;
  /* Measured against the DARKEST ground they land on, which is `--surface-2`,
     not white: the wells under empty states and inline suggestions dropped the
     old values to 4.28 and 4.31, which is a colour that looks fine and is not
     readable. Both now clear 4.5 on every surface in the product. */
  --ink-2: #516975;
  --ink-3: #5A6970;
  --line: #DCE6EC;
  --line-strong: #C3D3DD;

  --good: #157C5E;
  --good-wash: #E2F4EE;
  --bad: #C03E3E;
  --bad-wash: #FBEAEA;
  --note: #95650E;
  --note-wash: #FBF1DD;

  --shadow: 0 1px 2px rgba(38, 50, 56, 0.05), 0 4px 16px rgba(38, 50, 56, 0.06);
  --radius: 12px;
  --radius-sm: 8px;

  --font-display: "Poppins", "Segoe UI", system-ui, sans-serif;
  --font-ui: "Inter", "Segoe UI", system-ui, sans-serif;
  --font-mono: Consolas, "Cascadia Mono", monospace;
}

/* ---- Tokens: dark --------------------------------------------------------- */
:root[data-theme="dark"] {
  --lt-blue: #3BAEE4;
  --lt-blue-ink: #3BAEE4;
  --lt-blue-deep: #6BC4EE;
  --lt-blue-wash: #12303F;
  --lt-teal: #2BC9E8;
  --lt-teal-ink: #2BC9E8;
  --lt-teal-wash: #0E2E36;
  --lt-gold: #FFB13D;
  --lt-gold-ink: #FFB13D;
  --lt-gold-wash: #33260F;

  --bg: #10171D;
  --surface: #1A242C;
  --surface-2: #141D24;
  --ink: #E8EEF3;
  --ink-2: #9FB2BD;
  --ink-3: #7A909F;
  --line: #2A3641;
  --line-strong: #3A4956;

  --good: #35C79A;
  --good-wash: #10312A;
  --bad: #F07567;
  --bad-wash: #3A1D1B;
  --note: #E0A94E;
  --note-wash: #322813;

  --shadow: none;
}

/* ---- Base ------------------------------------------------------------------ */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, .display { font-family: var(--font-display); font-weight: 600; }
a { color: var(--lt-blue-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
code, .mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
  /* Explicit, not inherited: inline code sits inside muted .topic text often
     enough that inheriting made it 4.28:1 on its own tinted background. */
  color: var(--ink);
  background: var(--surface-2);
  padding: 1px 6px;
  border-radius: 5px;
}
.num { font-variant-numeric: tabular-nums; }

/* ---- Card ------------------------------------------------------------------
   The board's panels are generous: a wide corner, a shadow that lifts rather
   than outlines, and enough padding that the contents are not fighting the
   edge. `--radius-lg` and `--shadow-card` are defined further down with the
   rest of the board's furniture; both fall back sensibly if this file is ever
   loaded in pieces. */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg, 16px);
  box-shadow: var(--shadow-card, var(--shadow));
  padding: 20px 22px;
  margin-bottom: 16px;
}
.card > h2 + .topic:first-of-type { margin-top: -4px; }
.card > h2 {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.card > h2 .spacer { flex: 1; }

/* ---- Badge — flat, straight, always -------------------------------------- */
.badge {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--ink-2);
  white-space: nowrap;
  vertical-align: middle;
}
.badge.good { background: var(--good-wash); color: var(--good); }
.badge.bad { background: var(--bad-wash); color: var(--bad); }
.badge.note { background: var(--note-wash); color: var(--note); }
.badge.blue { background: var(--lt-blue-wash); color: var(--lt-blue-ink); }
.badge.teal { background: var(--lt-teal-wash); color: var(--lt-teal-ink); }
.badge.gold { background: var(--lt-gold-wash); color: var(--lt-gold-ink); }
:root[data-theme="dark"] .badge.gold { color: var(--lt-gold-ink); }

/* ---- Stat ------------------------------------------------------------------ */
.stat { display: flex; flex-direction: column; gap: 2px; min-width: 130px; }
.stat .v { font-family: var(--font-display); font-weight: 600; font-size: 22px; font-variant-numeric: tabular-nums; }
.stat .k { color: var(--ink-2); font-size: 12px; }
.statrow { display: flex; gap: 28px; flex-wrap: wrap; margin: 4px 0 6px; }

/* ---- Buttons --------------------------------------------------------------- */
.btn, button {
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  border-radius: var(--radius-sm);
  padding: 7px 16px;
  /* The fill carries white text, so it uses the ink blue: the brand colour
     itself only reaches 4.04:1 against white, which is a button you squint at. */
  border: 1px solid var(--lt-blue-ink);
  background: var(--lt-blue-ink);
  color: #fff;
  transition: filter 0.12s ease;
}
.btn:hover, button:hover { filter: brightness(1.07); }
button:disabled { opacity: 0.55; cursor: default; filter: none; }
.btn.ghost, button.ghost {
  background: transparent;
  color: var(--lt-blue-ink);
}
.btn.quiet, button.quiet, button.linkish {
  background: transparent;
  border-color: transparent;
  color: var(--lt-blue-ink);
  padding: 4px 8px;
}
button.linkish.danger, .btn.danger { color: var(--bad); border-color: transparent; background: transparent; }
/* Dark mode inverts the text on FILLED buttons, whose background is bright.
   Anything transparent keeps its own colour — the theme toggle spent a while
   at 1.18:1 because this rule reached it too. */
:root[data-theme="dark"] .btn:not(.ghost):not(.quiet):not(.linkish):not(.theme-toggle),
:root[data-theme="dark"] button:not(.ghost):not(.quiet):not(.linkish):not(.theme-toggle) {
  color: #0E1418;
}
:root[data-theme="dark"] .btn.ghost, :root[data-theme="dark"] button.ghost,
:root[data-theme="dark"] .btn.quiet, :root[data-theme="dark"] button.quiet,
:root[data-theme="dark"] button.linkish { color: var(--lt-blue); background: transparent; }
:root[data-theme="dark"] .theme-toggle { color: var(--ink-2); background: transparent; }
:root[data-theme="dark"] button.linkish.danger, :root[data-theme="dark"] .btn.danger { color: var(--bad); }

/* ---- Inputs ---------------------------------------------------------------- */
input, select, textarea {
  font: inherit;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 7px 11px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--lt-blue);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
/* A resting input should look like somewhere to type, and a focused one like
   the place the keyboard is going. */
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
  border-color: var(--line-strong);
}
input:focus, select:focus, textarea:focus {
  background: var(--surface);
  border-color: var(--lt-blue);
}
textarea { width: 100%; resize: vertical; }
label.setting { display: flex; flex-direction: column; gap: 4px; }
label.setting > span { color: var(--ink-2); font-size: 12px; font-weight: 500; }

/* ---- Ledger rows ----------------------------------------------------------- */
.ledger { border-top: 1px solid var(--line); }
.ledger .row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 10px;
  margin: 0 -10px;
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: background 0.12s ease;
}
.ledger .row:last-child { border-bottom: none; }
.ledger .row:hover { background: var(--surface-2); }
.ledger .row .when { color: var(--ink-3); font-size: 12px; min-width: 96px; font-variant-numeric: tabular-nums; }
.ledger .row .what { flex: 1; min-width: 0; }
.ledger .row .topic, .topic { color: var(--ink-2); font-size: 12.5px; }
.ledger .row .mono { background: none; font-size: 13px; font-variant-numeric: tabular-nums; }
a.rowlink { color: inherit; display: flex; }
a.rowlink:hover { background: var(--surface-2); text-decoration: none; }

/* ---- Empty states ----------------------------------------------------------
   An empty state is a real state, not a failure. It gets the same care as a
   full one: its own ground, and a sentence saying why it is empty. */
.empty {
  color: var(--ink-2);
  padding: 26px 22px;
  background: var(--surface-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg, 16px);
  text-align: center;
}
.empty .why {
  color: var(--ink-3);
  font-size: 12.5px;
  margin: 6px auto 0;
  max-width: 62ch;
  line-height: 1.6;
}

/* ---- Key-value ------------------------------------------------------------- */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 5px 20px; margin: 0; }
.kv dt { color: var(--ink-2); font-size: 13px; }
.kv dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 500; }

/* ---- Forms ----------------------------------------------------------------- */
.inline-form { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; align-items: center; }
.inline-form input { flex: 1; min-width: 150px; }
.settings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 20px; }
@media (max-width: 900px) { .settings-grid { grid-template-columns: 1fr; } }

/* ---- Doc body (recipes output, templates) ---------------------------------- */
.recipe-body h2 { font-size: 15px; margin: 16px 0 6px; }
.recipe-body h3 { font-size: 13.5px; margin: 12px 0 4px; color: var(--ink-2); }
.recipe-body blockquote { border-left: 3px solid var(--lt-blue); margin: 10px 0; padding: 2px 14px; color: var(--ink-2); }
.recipe-body .codeblock { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; overflow-x: auto; }
.recipe-body ul { margin: 6px 0; padding-left: 22px; }
.recipe-body li { margin: 3px 0; }

.section-rule {
  font-size: 12px; letter-spacing: .10em; text-transform: uppercase;
  color: var(--ink-3); margin: 26px 2px 10px; font-weight: 600;
}

/* ============================================================
   The board's own furniture.
   The brand board is not just a palette — it is a set of shapes:
   a stat card with the number large and a delta chip beside it, a
   soft curve under a gradient, rounded bars with one picked out,
   pill buttons, and an active nav item sitting in a wash of blue.
   Those live here so every page can reach for them.
   ============================================================ */

:root {
  --radius-lg: 16px;
  --radius-pill: 999px;
  /* Two shadows: a resting one and one for something you can click.
     Both are cool-tinted, because a neutral grey shadow on a quartz
     ground reads as dirt. */
  --shadow-card: 0 1px 2px rgba(38, 50, 56, 0.04), 0 6px 20px rgba(38, 50, 56, 0.07);
  --shadow-lift: 0 2px 6px rgba(10, 134, 194, 0.10), 0 12px 28px rgba(38, 50, 56, 0.10);
}
:root[data-theme="dark"] {
  --shadow-card: 0 1px 0 rgba(255, 255, 255, 0.03);
  --shadow-lift: 0 0 0 1px rgba(59, 174, 228, 0.22);
}

/* ---- Stat card ------------------------------------------------------------
   The unit the board leads with. Label small and quiet, number large in the
   display face, the delta underneath saying which way and against what. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.statcard {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 16px 18px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  color: inherit;
}
a.statcard { transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease; }
a.statcard:hover {
  text-decoration: none;
  box-shadow: var(--shadow-lift);
  border-color: var(--lt-blue);
  transform: translateY(-1px);
}
.statcard .k {
  color: var(--ink-2);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2px;
}
.statcard .v {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 27px;
  line-height: 1.15;
  color: var(--ink);
}
.statcard .topic { font-size: 12px; }
.statcard .delta-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-height: 20px; }
.statcard .spark { width: 100%; height: 34px; margin-top: 8px; display: block; }

/* The delta chip: colour AND an arrow AND a number, so it never depends on
   one channel. */
.delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--ink-2);
  white-space: nowrap;
}
.delta.up { background: var(--good-wash); color: var(--good); }
.delta.down { background: var(--bad-wash); color: var(--bad); }
.delta.flat { background: var(--surface-2); color: var(--ink-2); }

/* ---- Charts ---------------------------------------------------------------- */
.chart { width: 100%; height: auto; display: block; }
.chart-tick {
  font-family: var(--font-ui);
  font-size: 10.5px;
  fill: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.chart circle { transition: r 0.12s ease; }
.chart circle:hover { r: 5; }
.donut-wrap { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.donut { width: 168px; height: 168px; flex: none; }
.donut-total {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  fill: var(--ink);
  font-variant-numeric: tabular-nums;
}
.legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.legend li { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.legend .swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* ---- Pill button ----------------------------------------------------------
   The board's call-to-action shape. Not the default — a form's Save is a
   rectangle — this is for the one action a panel is really about. */
.btn.pill, button.pill {
  border-radius: var(--radius-pill);
  padding: 8px 20px;
  font-weight: 600;
  border-color: transparent;
  background: linear-gradient(135deg, var(--lt-blue-ink), var(--lt-teal-ink));
  color: #fff;
}
:root[data-theme="dark"] .btn.pill, :root[data-theme="dark"] button.pill {
  background: linear-gradient(135deg, var(--lt-blue), var(--lt-teal));
  color: #0E1418;
}
.btn.pill:hover, button.pill:hover { filter: brightness(1.08); }

/* ---- Section heading between card groups ---------------------------------- */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 26px 0 12px;
}
.section-head h2 { font-size: 15px; margin: 0; }
.section-head .topic { font-size: 12.5px; }
.section-head .spacer { flex: 1; }

/* Two charts side by side where there is room, stacked where there is not. */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  align-items: start;
}
.chart-grid .card { margin-bottom: 0; }
.note-line { margin: 0 0 12px; max-width: 92ch; }
/* A quiet line that still has to be noticed: the answer came from a model
   nobody chose, a figure that is not what it appears. Gold rather than red —
   nothing is broken, but it is not what was asked for either. */
.warn-line { color: var(--lt-gold-ink); }
/* A product's revenue shape, small, in the row it belongs to. */
.prod-spark { flex: none; width: 110px; }
.prod-spark .spark { height: 28px; }
@media (max-width: 720px) { .prod-spark { display: none; } }
/* Things worth knowing before you reply. Not warnings — context. */
.flags { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.flags li {
  color: var(--ink-2); font-size: 13px; padding: 8px 12px;
  background: var(--lt-gold-wash); border-radius: var(--radius-sm);
  border-left: 3px solid var(--lt-gold);
}
/* What was actually sent to somebody's AI. Long, monospaced, scrollable, and
   not truncated with an ellipsis — the point is being able to read all of it. */
.transcript {
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  max-height: 340px;
  overflow-y: auto;
  margin: 4px 0 14px;
}

/* The order registrations have to happen in. Numbered, because the number IS
   the information — a step done out of order is weeks lost. */
.path { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.path-step { padding: 16px 0; border-bottom: 1px solid var(--line); }
.path-step:last-child { border-bottom: none; }
.path-head { display: flex; gap: 14px; align-items: flex-start; }
.path-n {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--lt-blue-wash); color: var(--lt-blue-ink);
  font-family: var(--font-display); font-weight: 600; font-size: 14px;
}
.path-kv { margin: 10px 0 0 44px; grid-template-columns: 6.5rem 1fr; gap: 4px 16px; }
.path-kv dd { font-weight: 400; color: var(--ink-2); }
@media (max-width: 640px) { .path-kv { margin-left: 0; grid-template-columns: 1fr; } .path-kv dt { margin-top: 6px; } }
/* How setting up here is shaped, before the steps themselves. */
.path-shape {
  margin: 0 0 14px; padding: 12px 14px; max-width: 78ch;
  background: var(--lt-teal-wash); border-radius: var(--radius-sm);
  border-left: 3px solid var(--lt-teal); color: var(--ink-2);
}
/* Where a step has got to. Sits under the step rather than beside its title,
   because it is an answer to the step and not a label on it. */
.step-progress {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.step-progress select { max-width: 22rem; }

/* "Your AI is thinking." A pulse rather than a spinner or a bar: nothing here
   reports progress, so a bar would be an invention. The elapsed count beside it
   is the part that is actually true. */
.work { display: inline-flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.work-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--lt-blue); align-self: center;
  animation: work-pulse 1.4s ease-in-out infinite;
}
@keyframes work-pulse {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
/* Somebody who has asked not to see motion has asked for all of it, and a
   pulsing dot is exactly the kind that gets missed. */
@media (prefers-reduced-motion: reduce) {
  .work-dot { animation: none; opacity: 0.8; }
}

/* Commercial alternatives to doing a step yourself. Quiet by design: the
   self-service route above is the answer, and this is the fallback. Each entry
   carries its own disclosure, so no ordering can hide what is behind it. */
.providers { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.providers li { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.providers a { font-weight: 600; }

/* The traps in a structure change. Numbered would imply an order; these are
   simultaneous and each one has cost somebody money. */
.watchouts { margin: 0 0 16px; padding-left: 18px; max-width: 78ch; display: grid; gap: 8px; }
.watchouts li { color: var(--ink-2); }

/* Ways of trading. A card each, the current one marked, because the choice
   changes every step and cost below it. */
.statcard.struct { gap: 6px; }
.statcard.struct.on { border-color: var(--lt-blue); box-shadow: var(--shadow-lift); }
.struct-name { font-size: 19px !important; }
.struct-kv { margin-top: 16px; grid-template-columns: 9rem 1fr; gap: 6px 16px; }
.struct-kv dd { font-weight: 400; color: var(--ink-2); max-width: 72ch; }
@media (max-width: 640px) { .struct-kv { grid-template-columns: 1fr; } .struct-kv dt { margin-top: 6px; } }
/* Structures that are not really a choice here. Said, not offered. */
.ruled-out { margin: 16px 0 0; max-width: 86ch; line-height: 1.65; }
/* Badges sitting together need air between them, not just between their words. */
.badges { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
