/* Design tokens. Every colour in the app comes from here.
   Nothing hardcodes a hex outside this file, which is what keeps dark mode honest. */

:root {
  --lsr-bg:            #fbfbfa;
  --lsr-surface:       #ffffff;
  --lsr-surface-alt:   #f5f6f7;
  --lsr-line:          #e3e5e8;
  --lsr-text:          #16171a;
  --lsr-muted:         #6b7075;
  --lsr-faint:         #9ba1a7;
  --lsr-accent:        #0e9bb0;
  --lsr-accent-strong: #0b7d8e;
  --lsr-accent-soft:   #e6f5f8;
  --lsr-ok:            #1a7f4b;
  --lsr-warn:          #b45309;
  --lsr-bad:           #b02a2a;
  --lsr-shadow:        0 1px 2px rgba(16, 18, 20, .04);
  --lsr-radius:        10px;
}

[data-theme="dark"] {
  --lsr-bg:            #0f1214;
  --lsr-surface:       #171b1e;
  --lsr-surface-alt:   #1e2428;
  --lsr-line:          #2a3136;
  --lsr-text:          #e8eaec;
  --lsr-muted:         #9aa3a9;
  --lsr-faint:         #6d777e;
  --lsr-accent:        #27c2d6;
  --lsr-accent-strong: #4dd4e5;
  --lsr-accent-soft:   #12303a;
  --lsr-ok:            #43c98a;
  --lsr-warn:          #e0a24a;
  --lsr-bad:           #e56b6b;
  --lsr-shadow:        0 1px 2px rgba(0, 0, 0, .3);
}

* { box-sizing: border-box; }

html { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }

body {
  margin: 0;
  background: var(--lsr-bg);
  color: var(--lsr-text);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------- app shell ---------- */

.topbar {
  background: var(--lsr-surface);
  border-block-end: 1px solid var(--lsr-line);
  padding: 12px 20px;
  display: flex;
  align-items: center;
  gap: 20px;
  position: sticky;
  inset-block-start: 0;
  z-index: 20;
}
.topbar nav {
  display: flex;
  gap: 18px;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Fade the right edge so a cut-off item reads as "more", not as a bug. */
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
}
.topbar nav::-webkit-scrollbar { display: none; }
.topbar .actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
}
.topbar nav a {
  white-space: nowrap;
  flex: none;
  color: var(--lsr-muted);
  text-decoration: none;
  font-size: 14px;
  padding: 4px 0;
  border-block-end: 2px solid transparent;
  cursor: pointer;
}
.topbar nav a:hover { color: var(--lsr-text); }
.topbar nav a.on { color: var(--lsr-accent); border-block-end-color: var(--lsr-accent); }

.iconbtn {
  background: none;
  border: 1px solid var(--lsr-line);
  border-radius: 8px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  cursor: pointer;
  color: var(--lsr-muted);
  padding: 0;
}
.iconbtn:hover { color: var(--lsr-accent); border-color: var(--lsr-accent); }
.iconbtn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; }

main { max-width: 940px; margin: 0 auto; padding: 22px 20px 90px; }

/* ---------- Card ---------- */

.card {
  background: var(--lsr-surface);
  border: 1px solid var(--lsr-line);
  border-radius: var(--lsr-radius);
  box-shadow: var(--lsr-shadow);
  padding: 18px;
  margin-block-end: 14px;
}
.card h2 {
  font-size: 12.5px;
  margin: 0 0 14px;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--lsr-muted);
  font-weight: 600;
}

/* ---------- Pill ---------- */

.pill {
  display: inline-block;
  font-size: 11.5px;
  padding: 2px 9px;
  border-radius: 99px;
  border: 1px solid var(--lsr-line);
  color: var(--lsr-muted);
  white-space: nowrap;
}
.pill.ok   { color: var(--lsr-ok);   border-color: var(--lsr-ok); }
.pill.warn { color: var(--lsr-warn); border-color: var(--lsr-warn); }
.pill.bad  { color: var(--lsr-bad);  border-color: var(--lsr-bad); }

/* ---------- Bar ---------- */

.bar { height: 7px; background: var(--lsr-line); border-radius: 4px; overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--lsr-accent); transition: width .3s; }

/* ---------- buttons ---------- */

button, .btn {
  font: inherit;
  padding: 9px 15px;
  border: 1px solid var(--lsr-line);
  background: var(--lsr-surface);
  color: var(--lsr-text);
  border-radius: 8px;
  cursor: pointer;
}
button:hover, .btn:hover { border-color: var(--lsr-accent); color: var(--lsr-accent); }
button:disabled { opacity: .5; cursor: default; }
button.primary, .btn.primary {
  background: var(--lsr-accent); color: #fff; border-color: var(--lsr-accent);
}
button.primary:hover { background: var(--lsr-accent-strong); border-color: var(--lsr-accent-strong); color: #fff; }

input, select, textarea {
  font: inherit;
  padding: 9px 11px;
  border: 1px solid var(--lsr-line);
  border-radius: 8px;
  background: var(--lsr-surface);
  color: var(--lsr-text);
  width: 100%;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--lsr-accent-soft);
  border-color: var(--lsr-accent);
}

/* ---------- tables ---------- */

table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th, td { text-align: start; padding: 8px; border-block-end: 1px solid var(--lsr-line); }
th {
  font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--lsr-muted); font-weight: 600;
}
td.n, th.n { text-align: end; font-variant-numeric: tabular-nums; }
tr:last-child td { border-block-end: none; }

/* ---------- utility ---------- */

.muted { color: var(--lsr-muted); font-size: 13.5px; }
.faint { color: var(--lsr-faint); }
.row { display: flex; align-items: center; gap: 12px; }
.grow { flex: 1; }
.hide { display: none; }
.note {
  background: var(--lsr-surface-alt);
  border: 1px solid var(--lsr-line);
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 14px;
}
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.kpi { border: 1px solid var(--lsr-line); border-radius: 8px; padding: 12px 14px; }
.kpi b { display: block; font-size: 22px; font-variant-numeric: tabular-nums; }
.kpi span {
  font-size: 11.5px; color: var(--lsr-muted);
  text-transform: uppercase; letter-spacing: .05em;
}

/* ---------- responsive ----------

   Targets: iPhone 17 Pro Max, iPad in both orientations, desktop.

   Two iOS specifics drive most of this. First, 100vh on iOS Safari measures
   the viewport as if the address bar were hidden, so a full height layout
   ends up taller than the screen and the composer sits under the chrome.
   Use dvh instead, which tracks the visible area as the bar shows and hides.
   Second, Safari zooms the page when a focused input has a font size below
   16px, which then leaves the layout scrolled sideways. Every input here
   inherits 16px, so do not reduce it. */

@supports (height: 100dvh) {
  .fullheight { min-height: 100dvh; }
}

/* Respect the notch and the home indicator. */
.topbar {
  padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right));
  padding-block-start: max(12px, env(safe-area-inset-top));
}
main {
  padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right));
  padding-block-end: max(90px, calc(60px + env(safe-area-inset-bottom)));
}

/* Tables are the main overflow risk. Let the card scroll sideways rather
   than forcing the whole page wider than the screen. */
.card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { min-width: 100%; }

/* Touch targets. Apple's guidance is 44px; the desktop sizes are smaller. */
@media (pointer: coarse) {
  .iconbtn { width: 44px; height: 44px; }
  button, .btn { min-height: 44px; padding-block: 11px; }
  .topbar nav a { padding-block: 10px; }
  th, td { padding-block: 11px; }
  .choice { padding: 14px; }
  input, select, textarea { min-height: 44px; }
}

/* ---------- tablet, iPad portrait and landscape ---------- */

@media (max-width: 1024px) {
  main { max-width: 100%; }
}

/* ---------- phone ---------- */

@media (max-width: 640px) {
  .topbar {
    flex-wrap: wrap;
    gap: 10px 14px;
    padding-block-end: 8px;
  }
  .topbar nav {
    order: 3;
    width: 100%;
    gap: 20px;
    border-block-start: 1px solid var(--lsr-line);
    padding-block-start: 6px;
    margin-inline: calc(-1 * max(20px, env(safe-area-inset-left)))
                   calc(-1 * max(20px, env(safe-area-inset-right)));
    padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right));
  }
  main { padding-block-start: 16px; }
  .card { padding: 14px; border-radius: 8px; }
  table { font-size: 13.5px; }
  th, td { padding-inline: 6px; white-space: nowrap; }
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .kpi b { font-size: 19px; }
  h2 { font-size: 11.5px; }
}

/* Very narrow, iPhone SE class. */
@media (max-width: 380px) {
  .kpis { grid-template-columns: 1fr; }
  .topbar nav { gap: 16px; }
  .topbar nav a { font-size: 13.5px; }
}

/* ---------- print, for her to work on paper ---------- */

@media print {
  .topbar, .iconbtn, button { display: none; }
  .card { border: none; box-shadow: none; padding: 0; }
  body { background: #fff; color: #000; }
}

/* ---------- prose ----------

   Study material, rendered from markdown. Optimised for reading a module for
   twenty minutes, not for scanning a dashboard. Measure is capped near 70
   characters because long lines make the eye lose its place on return. */

.prose {
  font-size: 16.5px;
  line-height: 1.72;
  max-width: 70ch;
  color: var(--lsr-text);
}
.prose > *:first-child { margin-block-start: 0; }

.prose h2 {
  font-size: 22px;
  line-height: 1.3;
  margin-block: 34px 12px;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--lsr-text);
  font-weight: 650;
  padding-block-end: 8px;
  border-block-end: 1px solid var(--lsr-line);
}
.prose h3 {
  font-size: 17.5px;
  margin-block: 28px 10px;
  font-weight: 650;
  color: var(--lsr-text);
}
.prose h4 {
  font-size: 15.5px;
  margin-block: 22px 8px;
  font-weight: 650;
  color: var(--lsr-muted);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.prose p { margin-block: 0 16px; }

/* Bold is the load bearing emphasis in study material: rule names, the operative
   number, the trap. Give it real weight and a touch of accent so it catches the
   eye when skimming back over a page. */
.prose strong {
  font-weight: 650;
  color: var(--lsr-text);
}
.prose em { font-style: italic; color: var(--lsr-muted); }

.prose ul, .prose ol { margin-block: 0 16px; padding-inline-start: 24px; }
.prose li { margin-block-end: 7px; }
.prose li::marker { color: var(--lsr-accent); }

.prose code {
  font: 0.88em ui-monospace, Menlo, Consolas, monospace;
  background: var(--lsr-surface-alt);
  border: 1px solid var(--lsr-line);
  border-radius: 4px;
  padding: 1px 5px;
}
.prose pre {
  background: var(--lsr-surface-alt);
  border: 1px solid var(--lsr-line);
  border-radius: 8px;
  padding: 14px;
  overflow-x: auto;
  margin-block: 0 16px;
}
.prose pre code { background: none; border: 0; padding: 0; font-size: 13.5px; }

.prose blockquote {
  margin: 0 0 16px;
  padding: 2px 0 2px 16px;
  border-inline-start: 3px solid var(--lsr-accent);
  color: var(--lsr-muted);
}

.prose hr {
  border: 0;
  border-block-start: 1px solid var(--lsr-line);
  margin-block: 28px;
}

.prose .tablewrap { overflow-x: auto; margin-block: 0 18px; max-width: 100%; }
.prose table { font-size: 14px; min-width: 100%; }
.prose th {
  background: var(--lsr-surface-alt);
  font-size: 11.5px;
  white-space: nowrap;
}
.prose td { vertical-align: top; }

/* CURRENCY lines flag a rule that changed. Make them impossible to skim past. */
.prose p:has(> strong:first-child) { }

.prose a { color: var(--lsr-accent); text-underline-offset: 2px; }

@media (max-width: 640px) {
  .prose { font-size: 16px; line-height: 1.68; max-width: 100%; }
  .prose h2 { font-size: 19px; margin-block-start: 26px; }
  .prose h3 { font-size: 16.5px; }
}

/* ---------- cheat sheet ---------- */

.sheetrow {
  padding: 13px 0;
  border-block-end: 1px solid var(--lsr-line);
}
.sheetrow:last-child { border-block-end: 0; }
.sheetrow .nm { font-weight: 650; font-size: 15px; }
.sheetrow .fx {
  font: 14.5px ui-monospace, Menlo, Consolas, monospace;
  background: var(--lsr-surface-alt);
  border: 1px solid var(--lsr-line);
  border-radius: 6px;
  padding: 7px 10px;
  margin-block: 7px;
  overflow-x: auto;
  white-space: pre-wrap;
}
.sheetrow .use { font-size: 14px; color: var(--lsr-muted); }
.sheetrow .src { font-size: 12px; color: var(--lsr-faint); margin-block-start: 4px; }
.val { font-variant-numeric: tabular-nums; font-weight: 650; }

/* ---------- notes, docked ----------

   The reading column and the pad are siblings in a grid. Opening notes changes
   the grid template, so the text reflows into a narrower column instead of
   sitting underneath an overlay. Minimising collapses the second column to a
   rail and gives the width back. */

.readwrap { display: grid; grid-template-columns: minmax(0, 1fr); }
.readwrap.withnotes { grid-template-columns: minmax(0, 1fr) 300px; }
.readwrap.withnotes.mini { grid-template-columns: minmax(0, 1fr) 36px; }

.notebtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  font-size: 13.5px;
}
.notebtn svg { flex: none; }

.notepad {
  border-inline-start: 1px solid var(--lsr-line);
  background: var(--lsr-surface-alt);
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.notepad .nrail { display: none; }
.readwrap.mini .notepad .nbody { display: none; }
.readwrap.mini .notepad .nrail {
  display: grid;
  place-items: center;
  height: 100%;
  min-height: 160px;
  cursor: pointer;
  color: var(--lsr-muted);
  font-size: 12px;
  letter-spacing: .02em;
}
.readwrap.mini .notepad .nrail span { writing-mode: vertical-rl; }
.readwrap.mini .notepad .nrail:hover { color: var(--lsr-accent); background: var(--lsr-bg); }

.notepad .nbody { display: flex; flex-direction: column; height: 100%; }

.notepad .nhead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 8px 9px 13px;
  border-block-end: 1px solid var(--lsr-line);
}
.notepad .ntitle { font-size: 13px; }

.notepad .niconbtn {
  border: 0;
  background: none;
  color: var(--lsr-muted);
  font-size: 17px;
  line-height: 1;
  padding: 5px 9px;
  min-height: 0;
  border-radius: 6px;
  cursor: pointer;
}
.notepad .niconbtn:hover { color: var(--lsr-accent); background: var(--lsr-bg); }

.notepad textarea {
  flex: 1;
  border: 0;
  border-radius: 0;
  resize: none;
  min-height: 300px;
  padding: 13px;
  font-size: 14.5px;
  line-height: 1.65;
  background: var(--lsr-surface-alt);
}
.notepad textarea:focus { outline: none; border: 0; }

.notepad .nfoot {
  padding: 7px 13px;
  border-block-start: 1px solid var(--lsr-line);
  font-size: 11.5px;
}

/* Two columns need real width. Below this, stack: the pad becomes a sheet the
   text sits above, which still pushes rather than covers. */
@media (max-width: 900px) {
  .readwrap.withnotes,
  .readwrap.withnotes.mini { grid-template-columns: minmax(0, 1fr); }
  .notepad {
    border-inline-start: 0;
    border-block-start: 1px solid var(--lsr-line);
  }
  .notepad textarea { min-height: 220px; }
  .readwrap.mini .notepad .nrail {
    min-height: 0;
    padding: 12px;
    height: auto;
  }
  .readwrap.mini .notepad .nrail span { writing-mode: horizontal-tb; }
}

@media print {
  .notepad, .notebtn { display: none; }
  .readwrap.withnotes { grid-template-columns: minmax(0, 1fr); }
}


/* ---------- brand mark ----------

   The logo is teal, close to the accent token. Two files rather than one
   because the original ink reads at 3.46 against the dark surface, which is
   muddy; the dark variant is recoloured to the dark accent and reads at 8.06.
   CSS swaps them on the theme attribute so neither is ever on the wrong ground. */

.brand {
  height: 26px;
  width: auto;
  display: block;
  flex: none;
}
.brand-dark { display: none; }
[data-theme="dark"] .brand-light { display: none; }
[data-theme="dark"] .brand-dark { display: block; }

/* The sign in and set password screens are the brand moment, so the mark is
   larger there and the page title sits under it. */
.brand-hero { height: 54px; margin-inline: auto; margin-block-end: 18px; }

@media (max-width: 640px) {
  .brand { height: 22px; }
  .brand-hero { height: 44px; }
}

@media print {
  .brand-dark { display: none; }
  .brand-light { display: block; }
}


/* ---------- nav scroll indicator ----------

   The fade at the right edge says "there is more" but not "you can swipe".
   A teal bar that sizes to the visible fraction and slides as you scroll
   makes the gesture obvious, and shows how much is still off screen.

   It hides itself entirely when everything already fits, so on a wide screen
   there is no stray line under the nav. */

.navwrap {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.navwrap nav { flex: none; }

.navtrack {
  display: none;
  height: 3px;
  background: var(--lsr-line);
  border-radius: 2px;
  overflow: hidden;
}
.navtrack.on { display: block; }
.navtrack i {
  display: block;
  height: 100%;
  background: var(--lsr-accent);
  border-radius: 2px;
  transition: transform .08s linear;
}

@media (pointer: coarse) {
  .navtrack { height: 4px; }
}
@media print { .navtrack { display: none; } }


/* ---------- footer ----------

   Sits below the main column on every page. The badge is an SVG so it stays
   sharp on the iPad's display, and it is capped narrow because it is a mark of
   assurance rather than a feature of the page. */

.sitefoot {
  margin-block-start: 44px;
  padding-block: 22px 30px;
  padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right));
  border-block-start: 1px solid var(--lsr-line);
  display: flex;
  justify-content: center;
}
.sitefoot img {
  width: 190px;
  height: auto;
  display: block;
  opacity: .85;
}
[data-theme="dark"] .sitefoot img { opacity: .78; }

@media (max-width: 640px) {
  .sitefoot { margin-block-start: 32px; padding-block: 18px 26px; }
  .sitefoot img { width: 165px; }
}
@media print { .sitefoot { display: none; } }
