/* ============================================================
   joeltilson.com · assets/site.css
   The one stylesheet for the whole site. No webfonts, no icon
   fonts, no images, no dark mode, no animation beyond the
   150 ms colour transition on buttons.

   Base sections, in order:
     1. Tokens            7. Forms
     2. Reset             8. Cards
     3. Typography        9. Utilities
     4. Layout           10. Tables
     5. Header           11. Booking embed (/session)
     6. Footer           12. Print, base rules
     6b. Buttons

   Page-specific rules are APPENDED after the base under a
   banner comment named for the page, for example
   ==== /map ====. Never edit the base from a page task.
   ============================================================ */


/* ------------------------------------------------------------
   1. Tokens (docs/BUILD-BRIEF.md §3, verbatim)
   ------------------------------------------------------------ */
:root {
  --bg: #ffffff;
  --text: #111111;
  --muted: #5a5a5a;
  --rule: #e6e6e6;
  --card: #fafafa;
  --accent: #8b1e2d;        /* deep oxblood red, matches the cover */
  --accent-hover: #6e1622;
  --focus: #8b1e2d;
  --serif: Georgia, "Times New Roman", Times, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --measure: 720px;
}


/* ------------------------------------------------------------
   2. Reset
   ------------------------------------------------------------ */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 112.5%;              /* 18px at the browser default, scales with the reader's text-size setting */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;                  /* header, main (grows), footer */
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 1rem;                /* 18px */
  line-height: 1.6;
}

/* Author styles must never un-hide a [hidden] element.
   Config gating depends on this. */
[hidden] {
  display: none !important;
}

img,
svg {
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}

fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 1.25rem;
  min-width: 0;
}

legend {
  padding: 0;
}


/* ------------------------------------------------------------
   3. Typography
   Serif headings, system sans body. Large text gets tighter
   tracking and leading as it grows, body stays at zero.
   ------------------------------------------------------------ */
h1,
h2,
h3,
h4 {
  font-family: var(--serif);
  font-weight: 400;
  color: var(--text);
  overflow-wrap: break-word;
  margin: 0 0 0.6rem;
}

h1 {
  font-size: 2.2rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 1rem;
}

h2 {
  font-size: 1.5rem;
  line-height: 1.25;
  letter-spacing: -0.012em;
}

h3 {
  font-size: 1.2rem;
  line-height: 1.3;
  letter-spacing: -0.005em;
  font-weight: 700;
}

h4 {
  font-size: 1rem;
  line-height: 1.4;
  font-weight: 700;
}

/* Space above a heading only when something comes before it */
* + h2 {
  margin-top: 2.5rem;
}

* + h3 {
  margin-top: 1.75rem;
}

p {
  margin: 0 0 1rem;
}

.lead {
  font-size: 1.2rem;
  line-height: 1.55;
  margin-bottom: 1.25rem;
}

.small {
  font-size: 0.9rem;
  line-height: 1.5;
}

.muted {
  color: var(--muted);
}

strong,
b {
  font-weight: 600;
}

ul,
ol {
  margin: 0 0 1rem;
  padding-left: 1.4rem;
}

li {
  margin: 0 0 0.35rem;
}

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2rem 0;
}

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--accent-hover);
}

/* One visible focus ring for everything keyboard-reachable */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}


/* ------------------------------------------------------------
   4. Layout
   .wrap caps the line length at --measure and keeps 16px
   gutters on phones. Pages use <main class="wrap">.
   ------------------------------------------------------------ */
.wrap {
  width: 100%;
  max-width: calc(var(--measure) + 32px);   /* 720px of content plus the gutters */
  margin: 0 auto;
  padding-left: 16px;
  padding-right: 16px;
}

main {
  flex: 1 0 auto;
  padding-top: 2rem;
  padding-bottom: 3.5rem;
}

@media (min-width: 600px) {
  main {
    padding-top: 3rem;
  }
}

section + section {
  margin-top: 2.5rem;
}


/* ------------------------------------------------------------
   5. Header
   <header class="site-header"><div class="wrap">
     <a class="wordmark" href="/">Joel Tilson</a>
     <nav class="site-nav" aria-label="Site">Book · Map · Session</nav>
   </div></header>
   ------------------------------------------------------------ */
.site-header {
  border-bottom: 1px solid var(--rule);
}

.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--serif);
  font-size: 1.35rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--text);
  text-decoration: none;
}

.wordmark:hover {
  color: var(--accent);
}

.site-nav {
  display: flex;
  gap: 1.25rem;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text);
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}


/* ------------------------------------------------------------
   6. Footer
   <footer class="site-footer"><div class="wrap">
     <p class="site-footer-copy">© 2026 Joel Tilson · New Albany, Ohio</p>
     <p class="site-footer-links">Disclaimer, Privacy, phone, email</p>
     <p class="site-footer-note">Educational content. ...</p>
   </div></footer>
   ------------------------------------------------------------ */
.site-footer {
  border-top: 1px solid var(--rule);
  padding: 2rem 0 2.5rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

.site-footer p {
  margin: 0 0 0.5rem;
}

.site-footer a {
  color: var(--text);
}

.site-footer a:hover {
  color: var(--accent);
}

.site-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.25rem;
}

.site-footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.site-footer-note {
  margin-top: 0.5rem;
}


/* ------------------------------------------------------------
   6b. Buttons
   .button                 primary: accent background, white text
   .button.button-secondary white background, accent border and text
   .button-text            tertiary text button
   Links the brief calls buttons are <a class="button">,
   actions are <button type="button" class="button">.
   One primary button per screen.
   ------------------------------------------------------------ */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  min-height: 48px;
  padding: 0.6rem 1.5rem;
  background: var(--accent);
  color: #ffffff;
  border: 2px solid var(--accent);
  border-radius: 8px;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.button:hover,
.button:active {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: #ffffff;
}

.button-secondary {
  background: #ffffff;
  color: var(--accent);
}

.button-secondary:hover,
.button-secondary:active {
  background: var(--card);
  border-color: var(--accent-hover);
  color: var(--accent-hover);
}

.button-text {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.25rem 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--accent);
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.25;
  text-align: center;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color 150ms ease;
}

.button-text:hover,
.button-text:active {
  color: var(--accent-hover);
}

/* A vertical stack of actions at the end of a page or card */
.actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 1.5rem 0;
}

.actions .help {
  margin: -0.25rem 0 0;
}

@media (max-width: 599.98px) {
  .button {
    display: flex;
    width: 100%;
  }

  .actions {
    align-items: stretch;
  }

  .actions .button-text {
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .button,
  .button-text {
    transition: none;
  }
}


/* ------------------------------------------------------------
   7. Forms
   <div class="field">
     <label for="id">Label</label>
     <input id="id" type="text" aria-describedby="id-help">
     <p class="help" id="id-help">Helper text</p>
   </div>
   Radio groups:
   <fieldset><legend>Question</legend>
     <div class="choices">
       <label class="choice"><input type="radio" name="x"> known</label>
     </div>
   </fieldset>
   ------------------------------------------------------------ */
.field {
  margin: 0 0 1.25rem;
}

label,
legend {
  display: block;
  font-weight: 600;
  line-height: 1.4;
  margin: 0 0 0.4rem;
}

.help {
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
  margin: 0.4rem 0 0;
}

input[type="text"],
input[type="number"],
input[type="date"],
input[type="month"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="search"],
input:not([type]),
textarea,
select {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.75rem;
  font-family: var(--sans);
  font-size: 1rem;                /* 18px, stops iOS zooming */
  line-height: 1.4;
  color: var(--text);
  background: #ffffff;
  border: 1px solid var(--rule);
  border-radius: 8px;
}

input[type="text"],
input[type="number"],
input[type="date"],
input[type="month"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="search"],
input:not([type]),
textarea {
  -webkit-appearance: none;
  appearance: none;
}

textarea {
  resize: vertical;
}

input[type="text"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="search"]:focus,
input:not([type]):focus,
textarea:focus,
select:focus {
  border-color: var(--accent);
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

input[type="radio"],
input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--accent);
  cursor: pointer;
}

.choice {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 44px;
  margin: 0;
  font-weight: 400;
  cursor: pointer;
}

.choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.5rem;
}


/* ------------------------------------------------------------
   8. Cards
   ------------------------------------------------------------ */
.card {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 24px;
  margin: 0 0 24px;
}

/* Cards are exactly 24px apart, even when each card is a <section> */
.card + .card {
  margin-top: 0;
}

.card > :last-child {
  margin-bottom: 0;
}


/* ------------------------------------------------------------
   9. Utilities
   ------------------------------------------------------------ */
/* "Saved in this browser · time", right-aligned, muted */
.status {
  text-align: right;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
  margin: 0 0 1rem;
}

/* .row: fields side by side on desktop, stacked on phones.
   .grid-2: exactly two columns on desktop, stacked on phones. */
.row,
.grid-2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem 1.25rem;
  margin: 0 0 1.25rem;
}

.row > .field,
.grid-2 > .field {
  margin: 0;
}

@media (min-width: 600px) {
  .row {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }

  .grid-2 {
    grid-template-columns: 1fr 1fr;
  }
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ------------------------------------------------------------
   10. Tables
   Wrap a wide table in <div class="table-wrap"> so it scrolls
   inside itself on phones and the page never scrolls sideways.
   Numeric cells take class "num".
   ------------------------------------------------------------ */
table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1.5rem;
  font-variant-numeric: tabular-nums;
}

caption {
  text-align: left;
  font-weight: 600;
  padding: 0 0 0.5rem;
}

th,
td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}

th {
  font-weight: 600;
}

thead th {
  border-bottom: 2px solid var(--rule);
}

tbody tr:nth-child(even) td {
  background: var(--card);
}

.num {
  text-align: right;
  white-space: nowrap;
}

.table-wrap {
  overflow-x: auto;
  margin: 0 0 1.5rem;
}

.table-wrap table {
  margin: 0;
}


/* ------------------------------------------------------------
   11. Booking embed (/session)
   site.js creates this element only when SESSION_MODE is
   "calendly" and CALENDLY_URL is set. The Calendly iframe is
   height 100%, so the box needs a definite height.
   ------------------------------------------------------------ */
.calendly-inline-widget {
  width: 100%;
  min-width: 0;
  height: 700px;
  min-height: 700px;
  margin: 0 0 1.5rem;
}


/* ------------------------------------------------------------
   12. Print, base rules
   White page, black text, no nav links, no buttons, no footer.
   Fields print as their value on a ruled line, so an empty
   field prints as a blank line. Pages with a print view
   (/map, /ledger, /calendar) append their own rules.
   ------------------------------------------------------------ */
@media print {
  @page {
    margin: 18mm 16mm;
  }

  html {
    font-size: 12pt;
  }

  body {
    display: block;
    background: #ffffff;
    color: #000000;
  }

  .wrap {
    max-width: none;
    padding: 0;
  }

  main {
    padding: 0;
  }

  h1,
  h2,
  h3,
  h4,
  p,
  li,
  label,
  legend,
  .lead,
  .help,
  .muted,
  .status,
  th,
  td {
    color: #000000;
  }

  a {
    color: #000000;
    text-decoration: none;
  }

  .site-header,
  .site-nav,
  .site-footer,
  .button,
  .button-text,
  .actions,
  button {
    display: none !important;
  }

  .card {
    background: #ffffff;
    border: 1px solid #000000;
    border-radius: 0;
    padding: 12pt;
    margin: 0 0 12pt;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  input[type="text"],
  input[type="number"],
  input[type="date"],
  input[type="month"],
  input[type="email"],
  input[type="tel"],
  input[type="url"],
  input[type="search"],
  input:not([type]),
  textarea,
  select {
    min-height: 0;
    padding: 0.2rem 0;
    background: #ffffff;
    color: #000000;
    border: 0;
    border-bottom: 1px solid #000000;
    border-radius: 0;
    outline: 0;
  }

  textarea {
    resize: none;
    overflow: hidden;
  }

  tbody tr:nth-child(even) td {
    background: #ffffff;
  }

  th,
  td {
    border-bottom-color: #000000;
  }

  .calendly-inline-widget {
    display: none;
  }
}


/* ============================================================
   ==== /map ====
   The Recapture Map. Scoped to main.map. Screen rules, then
   the phone layout of the financing table, then the print view.
   ============================================================ */

/* Print-only elements stay out of the screen layout:
   the "From Ask Nobody ..." line, the readiness words and the
   textarea mirrors that map.js keeps in sync. */
.map .map-print-line,
.map .ready-print,
.map .ta-print {
  display: none;
}

/* A helper that sits above a group of rows instead of under a field */
.map .help-above {
  margin: 0 0 1rem;
}

/* Repeating rows: Objection Ledger and Money sitting still.
   Fields in a .row, the Remove text button beside them on
   desktop and under them on phones. */
.map .rep-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.25rem 1rem;
  align-items: end;
  padding: 0 0 0.75rem;
  margin: 0 0 1rem;
  border-bottom: 1px solid var(--rule);
}

.map .rep-row > .row {
  margin: 0;
  align-items: end;             /* inputs line up when a label wraps */
}

/* Remove is the least important control on the page, so it does not
   spend the accent. It gets the accent back on hover and press. */
.map .rep-remove {
  font-size: 0.9rem;
  justify-self: start;
  color: var(--muted);
}

.map .rep-remove:hover,
.map .rep-remove:active {
  color: var(--accent);
}

@media (min-width: 600px) {
  .map .rep-row {
    grid-template-columns: 1fr auto;
  }
}

/* "Add a row" at six rows, "Remove" at one row */
.map .button-text:disabled {
  color: var(--muted);
  text-decoration: none;
  cursor: default;
}

/* Live total under the idle accounts: the label is body weight, the
   figure carries the weight, and the digits keep a fixed width */
.map .map-total {
  font-weight: 400;
  margin: 0 0 1.75rem;
}

.map #idle_total {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* A currency value the page could not read, on screen only so the
   print view keeps its black rule */
@media screen {
  .map [data-currency][aria-invalid="true"] {
    border-color: var(--accent);
  }
}

/* Two piles, kept separate: the highlighted sub-box */
.map .piles {
  background: #ffffff;
  border: 1px solid var(--accent);
  border-radius: 12px;
  padding: 1rem;
  margin: 0 0 1.25rem;
}

.map .piles h3 {
  margin-top: 0;
}

.map .piles .grid-2 {
  margin-bottom: 0;
}

/* Open questions sit last in the card */
.map #open_questions {
  margin-bottom: 0;
}

.map #open_questions .field:last-child {
  margin-bottom: 0;
}

/* Existing financing table, desktop: the column header is the
   visible label, the per-input label is for screen readers. */
.map .fin-table th,
.map .fin-table td {
  padding: 0.4rem 0.3rem;
  vertical-align: bottom;
}

.map .fin-table th {
  font-size: 0.9rem;
  line-height: 1.3;
}

.map .fin-table input[type="text"] {
  min-width: 0;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

.map .fin-col-purpose {
  min-width: 150px;
}

.map .fin-col-balance,
.map .fin-col-payment {
  min-width: 115px;
}

.map .fin-col-rate {
  min-width: 85px;
}

.map .fin-col-ends {
  min-width: 95px;
}

@media (min-width: 600px) {
  .map .fin-label {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
}

/* Existing financing table, phones: each row is a stacked
   mini-card with its labels visible. Screen only, so print
   always gets the table. */
@media screen and (max-width: 599.98px) {
  .map .table-wrap {
    overflow: visible;
  }

  .map .fin-table,
  .map .fin-table tbody,
  .map .fin-table tr,
  .map .fin-table td {
    display: block;
    width: 100%;
  }

  .map .fin-table thead {
    display: none;
  }

  .map .fin-table tr {
    background: #ffffff;
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: 0.75rem;
    margin: 0 0 0.75rem;
  }

  .map .fin-table td,
  .map .fin-table tbody tr:nth-child(even) td {
    padding: 0 0 0.75rem;
    border: 0;
    background: transparent;
  }

  .map .fin-table td:last-child {
    padding-bottom: 0;
  }

  .map .fin-table input[type="text"] {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
}

/* The line above the bottom actions */
.map .map-bring {
  margin: 2rem 0 0;
}

.map .map-bring + .actions {
  margin-top: 0.75rem;
}

/* Print: the title, the "From Ask Nobody" line, then the eight
   cards one per page with every label and value. Radios print
   as words, textareas print as their mirrored text, the
   financing table prints as a table. */
@media print {
  .map .map-print-line {
    display: block;
    margin: -0.5rem 0 1rem;
  }

  .map .lead,
  .map .small,
  .map .status,
  .map .map-bring,
  .map .choices,
  .map .fin-label,
  .map .fin-remove-cell,
  .map textarea {
    display: none !important;
  }

  .map .card + .card {
    break-before: page;
    page-break-before: always;
  }

  .map .ready-print,
  .map .ta-print {
    display: block;
    min-height: 1.6em;
    padding: 0.2rem 0;
    border-bottom: 1px solid #000000;
  }

  .map .ta-print {
    min-height: 3.2em;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  .map .rep-row {
    padding-bottom: 0.25rem;
    margin-bottom: 0.5rem;
    border-bottom: 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .map .piles {
    border: 1px solid #000000;
    border-radius: 0;
  }

  .map .table-wrap {
    overflow: visible;
  }

  .map .fin-table th,
  .map .fin-table td {
    padding: 0.3rem 0.2rem;
    vertical-align: bottom;
  }
}


/* ============================================================
   ==== /ledger ====
   The loan ledger. Scoped to main.ledger. The four inputs in one
   row, the output box, the amortization table, then print.
   ============================================================ */

/* The four inputs line up at the bottom when a label wraps.
   The start month gets more room so "September 2026" and the
   picker fit on one line. */
.ledger .row {
  align-items: end;
  margin-bottom: 0.75rem;
}

@media (min-width: 600px) {
  .ledger .row {
    grid-template-columns: minmax(180px, 1.25fr) repeat(3, minmax(0, 1fr));
  }
}

/* The helper sits under the whole row, not under one field */
.ledger .ledger-help {
  margin: 0 0 1.5rem;
}

/* The output box: the payment large, two lines under it */
.ledger .ledger-out p {
  margin: 0 0 0.35rem;
}

.ledger .ledger-payment {
  font-size: 1.2rem;
  line-height: 1.4;
}

.ledger #led_payment {
  display: inline-block;
  font-family: var(--serif);
  font-size: 2.2rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* Month cells are row headers, read as text, never wrapped */
.ledger tbody th {
  font-weight: 400;
  white-space: nowrap;
}

/* The base zebra stripe covers td only. The month cell is a th,
   so it takes the same stripe here or the even rows have a gap
   in the first column. */
.ledger tbody tr:nth-child(even) th {
  background: var(--card);
}

/* Print: the inputs as values, the output box, then the whole
   table with its header on every page. */
@media print {
  .ledger .row {
    grid-template-columns: minmax(180px, 1.25fr) repeat(3, minmax(0, 1fr));
  }

  .ledger .ledger-out {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .ledger .table-wrap {
    overflow: visible;
  }

  .ledger thead {
    display: table-header-group;
  }

  .ledger tr {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .ledger tbody tr:nth-child(even) th {
    background: #ffffff;
  }
}


/* ============================================================
   ==== /calendar ====
   The first ninety days. Scoped to main.calendar. Five numbered
   cards, each with a Date field and a Done box, then print.
   ============================================================ */

/* The list carries no native markers. Each card numbers itself
   through a counter so the number sits inside the card, not in
   a gutter beside it. */
.calendar .cal-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: cal-step;
}

.calendar .cal-step {
  counter-increment: cal-step;
}

/* The card title: an h2 at the h2 token, numbered */
.calendar .cal-title {
  margin: 0 0 0.5rem;
}

.calendar .cal-title::before {
  content: counter(cal-step) ". ";
}

/* Date and Done: stacked on phones, side by side from 600px,
   the Done box lined up with the bottom of the Date input. */
.calendar .cal-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem 1.5rem;
  align-items: end;
}

.calendar .cal-fields .field {
  margin: 0;
}

@media (min-width: 600px) {
  .calendar .cal-fields {
    grid-template-columns: minmax(0, 260px) auto;
  }
}

/* Print: the title, the lead and the five cards on one page.
   Each card is compact: the Date label sits on the same line as
   its value (a black underline from the base rules, blank when
   empty) with the Done box beside it. */
@media print {
  .calendar .cal-step {
    padding: 8pt 10pt;
    margin-bottom: 8pt;
  }

  .calendar .cal-title {
    margin-bottom: 0.25rem;
  }

  .calendar .cal-step p {
    margin-bottom: 0.5rem;
  }

  .calendar .cal-fields {
    grid-template-columns: minmax(0, 220px) auto;
    gap: 0 1.5rem;
    align-items: baseline;
  }

  .calendar .cal-fields .field {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
  }

  .calendar .cal-fields label[for] {
    flex: 0 0 auto;
    margin: 0;
  }

  .calendar .cal-fields input[type="text"] {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }

  .calendar .choice {
    min-height: 0;
  }

  .calendar input[type="checkbox"] {
    accent-color: #000000;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}


/* ============================================================
   ==== /session ====
   Book your strategy session. Scoped to main.session. The four
   short blocks and the booking block use the base rules. The
   booking states (#booking-embed, #booking-audit,
   #booking-closed) are switched by site.js, the embed box itself
   is styled in base section 11.
   ============================================================ */

/* The "Build your Map first" link is the one tap target in the
   copy, so it gets a 44px hit area like the nav and footer links */
.session .session-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}


/* ============================================================
   ==== /home ====
   The home page, plus the two small rules that /privacy needs.
   /disclaimer, 404, /book and /audit use the base rules only.
   Scoped to main.home and main.privacy.
   ============================================================ */

/* The hero's secondary text link gets a 44px tap target and
   sits centred under the full-width button on phones */
.home .hero-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

@media (max-width: 599.98px) {
  .home .actions .hero-link {
    justify-content: center;
  }
}

/* The muted fallback line under the config-gated "Get the book"
   button sits inside the actions stack, so the gap spaces it */
.home .actions > .muted {
  margin: 0;
}

/* /privacy: the "or to" between the email and the address
   appears only once site.js has unhidden the email link */
.privacy a[data-contact-email][hidden] + .contact-or {
  display: none;
}


/* ============================================================
   ==== /walkthrough ====
   The Recapture Walkthrough. Scoped to main.walkthrough. The gate
   (#gate) and the course (#course) share the page and
   walkthrough.js shows one of them. Eight module cards, each with
   a 16:9 embed box that holds either the Vimeo player or the
   "Coming soon" box, a small Watched box, and the line under.
   ============================================================ */

/* Links inside the copy (the gate's "Get the Walkthrough", the
   Map, ledger and calendar links under the videos) get a 44px
   hit area through padding around the inline box. Inline padding
   leaves the line height alone and lets a long link wrap on a
   phone instead of overflowing. */
.walkthrough .gate-link,
.walkthrough .module-next a {
  padding: 0.65rem 0;
}

/* The module list carries no markers or indent */
.walkthrough .modules {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* The embed box keeps 16:9 at every width through its top
   padding. The player or the "Coming soon" text fills it. */
.walkthrough .embed {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
  margin: 0 0 0.5rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 8px;
  overflow: hidden;
}

.walkthrough .embed > iframe,
.walkthrough .embed > .embed-soon {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.walkthrough .embed > iframe {
  display: block;
  border: 0;
}

.walkthrough .embed > .embed-soon {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  color: var(--muted);
  font-family: var(--serif);
  font-size: 1.2rem;
}

/* The Watched box: small, under the video, on the right */
.walkthrough .watched {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

/* The one primary button sits directly under Module 7's card */
.walkthrough .modules + .actions {
  margin-top: 0;
}

/* #course follows the hidden #gate, so it must not pick up the
   section + section gap */
.walkthrough > section[hidden] + section {
  margin-top: 0;
}
