/* The public pages: sign up, sign in, the password pages, the trial steps, and
   the page anyone meets when something goes wrong.

   Each is one taped slip on the exercise book's white grid page, under the
   cobalt nav and above the back cover. book.css loads first and brings the
   tokens, the keys, the nav, the page, the tape, the stepper and the back
   cover; this file adds the page shell, the slip, the form fields and the
   error chip. */

html {
  -webkit-text-size-adjust: 100%;
  background: var(--cover);
  scrollbar-color: rgba(255, 255, 255, 0.5) var(--cover-deep);
}

body.pub {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--cover);
  color: var(--ink);
  font-family: var(--f-print);
  font-size: 1.0625rem;
  line-height: 1.55;
  caret-color: var(--pen);
  -webkit-font-smoothing: antialiased;
}

.pub .page {
  flex: 1 0 auto;
  width: 100%;
  padding-top: clamp(40px, 6vw, 72px);
  padding-bottom: clamp(56px, 8vw, 96px);
}

.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ the slip

   One piece of paper taped onto the page, holding one form. */

.slip {
  position: relative;
  max-width: 34rem;
  margin: 0 auto;
  padding: clamp(30px, 3.2vw, 44px);
  background: var(--slip);
  box-shadow: var(--slip-shadow);
  transform: rotate(var(--rot, -0.35deg));
}
.slip h1 {
  margin: 0;
  font-size: clamp(1.95rem, 1.35rem + 1.8vw, 2.6rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.018em;
}
:where(.slip) p { margin: 0 0 12px; }

/* The line under the heading and the error chip share one slot of one height,
   so a form that comes back with an error does not move. Only a lede directly
   above a form takes the reserved height; a lede with no error to swap with
   (the welcome page's trial line) sits at its own height. On the account step
   the lede and its count fold share the slot (.plan-head, below). */
.lede:has(+ form), .form-error { min-height: calc(4.65em + 16px); margin: 14px 0 22px; }
.lede { margin: 14px 0 22px; color: var(--ink-soft); }
.form-error {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  font-weight: 700;
  color: var(--red);
  background: var(--slip);
  border: 2px solid var(--red);
  border-radius: 8px;
}
.form-note {
  min-height: 3.2em;
  margin: 14px 0 22px;
  padding: 6px 12px;
  font-weight: 700;
  color: var(--done);
  background: var(--done-bg);
  border-radius: 8px;
}

/* ------------------------------------------------------------------ fields */

.field { margin: 0 0 20px; }
.field > label { display: block; margin: 0 0 6px; font-weight: 700; }
.field input[type="text"], .field input[type="email"],
.field input[type="password"], .field input[type="number"] {
  width: 100%;
  min-height: 56px;
  padding: 0 14px;
  font: 400 1.1rem/1.2 var(--f-print);
  color: var(--ink);
  background: var(--key);
  border: 2px solid var(--key-line);
  border-radius: 10px;
}
.field input:focus-visible { border-color: var(--pen); }
.field input[aria-invalid="true"] { border-color: var(--red); }
.hint { margin: 6px 0 0; font-size: 0.95rem; color: var(--ink-soft); }

/* A password field with its Show key inside the right end. The key stays
   hidden until public.js runs, because without the script it does nothing. */
.pw { position: relative; }
.field .pw input { padding-right: 5.5rem; }
.pw-show {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 5rem;
  min-height: 56px;
  padding: 0 14px;
  font: 700 1rem var(--f-print);
  color: var(--pen);
  background: none;
  border: 0;
  border-radius: 0 10px 10px 0;
  cursor: pointer;
}
.pw-show:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.pw-show[hidden] { display: none; }

.check {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  margin: 0 0 12px;
  font-weight: 700;
  cursor: pointer;
}
.check input { flex: none; width: 24px; height: 24px; margin: 0; accent-color: var(--pen); }

.slip .key { margin-top: 6px; }
.slip .key-start { width: 100%; border-color: var(--start-edge); }
/* The error page's key sits straight under the h1, with no lede or error chip
   between them, so it needs its own clearance rather than the 6px every
   other slip's key keeps below a line of text. */
.slip h1 + .key { margin-top: 22px; }
.fine { margin: 14px 0 0; font-size: 0.95rem; color: var(--ink-soft); }
/* What the parent agrees to, directly above the key that agrees to it. */
.fine.agree { margin: 0 0 14px; }

.slip-links { display: flex; flex-wrap: wrap; gap: 0 26px; margin: 16px 0 0; }
.slip-links a { display: inline-flex; align-items: center; min-height: 56px; font-weight: 700; }

@media (max-width: 620px) {
  .slip { padding: 28px 20px 26px; }
}

/* ------------------------------------------------------------------ a child, in the sign-up shell

   The parent area's child fields (_child_fields.html), set on the slip the
   way the sign-up form's fields are: a bold label, a 56px field, the help in
   Ink Soft, and the school years as 56px radio rows, three across and two
   across on a phone. */

.slip.setup .lede:has(+ form) { min-height: 0; }
.child-fields > label { display: block; margin: 0 0 6px; font-weight: 700; }
.child-fields > input[type="text"] {
  width: 100%;
  min-height: 56px;
  padding: 0 14px;
  font: 400 1.1rem/1.2 var(--f-print);
  color: var(--ink);
  background: var(--key);
  border: 2px solid var(--key-line);
  border-radius: 10px;
}
.child-fields > input:focus-visible { border-color: var(--pen); }
.child-fields .help { margin: 6px 0 20px; font-size: 0.95rem; color: var(--ink-soft); }
.child-fields .years {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 12px;
  min-width: 0;
  margin: 0 0 20px;
  padding: 0;
  border: 0;
}
.child-fields .years legend { margin: 0 0 6px; padding: 0; font-weight: 700; }
.child-fields .year-pick {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  font-weight: 700;
  cursor: pointer;
}
.child-fields .year-pick input { flex: none; width: 24px; height: 24px; margin: 0; accent-color: var(--pen); }
.child-fields .year-pick.coming { color: var(--ink-soft); font-weight: 400; cursor: default; }
.child-fields .year-pick .meta { font-size: 0.85rem; }
@media (max-width: 620px) {
  .child-fields .years { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ------------------------------------------------------------------ you are all set

   The finish slip: the pen tick before the h1, then what happens next as an
   ordered list with pen numerals, each item led by a bold printed line, the
   family code in its own type, and the one key. The welcome page after
   Stripe draws the same tick before its h1. */

.slip h1 .done-tick {
  display: inline-block;
  width: 40px;
  height: 40px;
  margin: 0 12px 0 0;
  vertical-align: -0.12em;
  fill: none;
  stroke: var(--done);
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
.ready-h { margin: 26px 0 10px; padding: 16px 0 0; font-size: 1.2rem; font-weight: 800; line-height: 1.2; border-top: 2px solid var(--rule); }
.ready-list { margin: 0 0 22px; padding: 0; list-style: none; counter-reset: next; }
.ready-list li {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: 10px;
  padding: 12px 0;
  border-top: 1px solid var(--key-line);
  counter-increment: next;
}
.ready-list li:first-child { border-top: 0; padding-top: 4px; }
.ready-list li::before {
  content: counter(next);
  font-family: var(--f-pen);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--pen);
}
.ready-list b { font-weight: 800; }
.ready-list .url { font-weight: 700; overflow-wrap: anywhere; }
.ready-code { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin: 0; padding: 16px 0 0; border-top: 2px solid var(--rule); }
.ready-code-label { font-weight: 800; }
.ready-code-value {
  font-family: var(--f-code);
  font-size: clamp(2rem, 7vw, 3rem);
  font-weight: 700;
  letter-spacing: 0.18em;
  line-height: 1.1;
  color: var(--pen);
}
.ready-code-help { margin: 4px 0 22px; color: var(--ink-soft); }

/* ------------------------------------------------------------------ a document

   The Terms of Use and the Privacy Policy: pages of reading printed straight
   onto the grid page, with no slip, tape or tilt. One column at a reading
   measure, the version below the heading, and each table ruled in ink. A wide
   table scrolls inside its own box, so the page never scrolls sideways. */

.doc { max-width: 44rem; margin: 0 auto; overflow-wrap: break-word; }
.doc h1 {
  margin: 0;
  font-size: clamp(1.95rem, 1.35rem + 1.8vw, 2.6rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.018em;
}
.doc-meta { margin: 10px 0 30px; font-size: 0.9rem; color: var(--ink-soft); }
.doc h2 {
  margin: 2.2em 0 0.6em;
  font-size: clamp(1.35rem, 1.1rem + 0.7vw, 1.7rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.doc p { margin: 0 0 14px; }
.doc ul { margin: 0 0 16px; padding: 0 0 0 1.3em; }
.doc li { margin: 0 0 6px; }
.doc code { font-family: var(--f-code); font-size: 0.95em; }
.doc-table { margin: 0 0 18px; overflow-x: auto; }
.doc table { width: 100%; border-collapse: collapse; font-size: 1rem; line-height: 1.45; }
.doc th, .doc td { padding: 10px 12px 10px 0; text-align: left; vertical-align: top; }
.doc th { font-weight: 700; border-bottom: 2px solid var(--rule); }
.doc td { border-bottom: 1px solid var(--ink-soft); }
.doc td:first-child, .doc th:first-child { min-width: 9rem; }

/* ------------------------------------------------------------------ the trial steps

   Account, Card, Children: three cells drawn in pen, the way the working
   diagrams on the front page are drawn. A card-free sign-up has two,
   Account and Children, as wide as the slip below them. On the finish page
   every cell is done. */

.progress {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 40rem;
  margin: 0 auto 40px;
  padding: 0;
  list-style: none;
}
.progress li {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  margin-left: -2px;
  padding: 6px 14px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--paper);
  border: 2px solid var(--pen);
}
.progress li:first-child { margin-left: 0; border-radius: 8px 0 0 8px; }
.progress li:last-child { border-radius: 0 8px 8px 0; }
.progress .pen { font-size: 1.6rem; font-weight: 700; line-height: 1; }
.progress [aria-current="step"] {
  color: var(--ink);
  background-image: linear-gradient(var(--tint), var(--tint));
}
.progress .done { color: var(--done); background: var(--done-bg); }
.progress .done .pen { color: var(--done); }
.progress.progress-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 34rem; }

/* ---- how many children. The stepper's keys come from book.css; without the
   script they stay hidden and the number box alone takes the count. */

.count { margin: 0 0 8px; }
.count > label { display: block; margin: 0 0 8px; font-weight: 700; }
.count input[type="number"] {
  width: 5.5rem;
  min-height: 56px;
  padding: 0 10px;
  font: 800 1.6rem/1 var(--f-print);
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--ink);
  background: var(--key);
  border: 2px solid var(--key-line);
  border-radius: 10px;
}
/* book.css's .key sets display: inline-flex on every key, the stepper's two
   pen keys included, which otherwise beats the browser's own [hidden] rule.
   This wins on specificity, so the keys stay hidden until public.js unhides
   them. */
.count .key-step[hidden] { display: none; }
.total { margin: 18px 0 0; font-weight: 700; color: var(--ink-soft); }
.total .pen { font-size: clamp(2.4rem, 1.9rem + 1.6vw, 3.2rem); font-weight: 700; line-height: 1; color: var(--pen); }
.working { min-height: 1.3em; margin: 6px 0 18px; font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.55rem); line-height: 1.25; }
.count-rule { color: var(--ink-soft); }

/* ---- the account step's count, folded under its lede: a pen plus that
   turns to a minus when open, the way the worked answers open. Inside, the
   stepper, and a plain key that only shows without the script.

   The lede and the fold sit in one slot as tall as the error chip and the
   fold together (14px + the chip + 22px - 10px + the 56px summary + 22px),
   so the fold stays right under a short lede and the fields below do not
   move when the chip takes the lede's place. */

.plan-head { display: flow-root; min-height: calc(4.65em + 120px); }
.count-change { margin: -10px 0 22px; }
.count-change summary {
  position: relative;
  display: flex;
  align-items: center;
  width: fit-content;
  min-height: 56px;
  padding-right: 40px;
  font-weight: 700;
  color: var(--pen);
  list-style: none;
  cursor: pointer;
}
.count-change summary::-webkit-details-marker { display: none; }
.count-change summary:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.count-change summary::before,
.count-change summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 50%;
  width: 18px;
  height: 3px;
  margin-top: -1.5px;
  background: var(--pen);
  border-radius: 2px;
  transition: transform 180ms var(--ease);
}
.count-change summary::after { transform: rotate(90deg); }
.count-change[open] summary::after { transform: rotate(0deg); }
.count-change form { padding: 14px 0 4px; border-top: 2px solid var(--rule); }
.count-change .count-rule { margin: 0 0 14px; }
.count-change [data-count-update][hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .count-change summary::after { transition: none; }
}

/* ---- how the free trial runs: today, day 7, day 14, on a pen-drawn line */

.start-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 80px);
  align-items: start;
  max-width: 64rem;
  margin: 0 auto;
}
.start-in .slip { max-width: none; margin: 0; }
.how h2 { margin: 0 0 18px; font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); font-weight: 800; line-height: 1.15; }
.timeline { position: relative; margin: 0; padding: 0; list-style: none; }
.timeline::before {
  content: "";
  position: absolute;
  top: 18px;
  bottom: 18px;
  left: 13px;
  width: 2px;
  background: var(--pen);
}
.timeline li { position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 16px; padding: 0 0 26px; }
.timeline li:last-child { padding-bottom: 0; }
.timeline .dot {
  width: 28px;
  height: 28px;
  margin-top: 4px;
  background: var(--paper);
  border: 2px solid var(--pen);
  border-radius: 50%;
}
.timeline li:first-child .dot { background: var(--done-bg); border-color: var(--done); }
.timeline .day { display: block; font-size: 1.45rem; font-weight: 700; line-height: 1.2; }
.timeline .when { display: block; font-weight: 700; }
.timeline .what { display: block; color: var(--ink-soft); }

/* What makes the trial safe to start, each line led by a pen mark. */
.trust {
  display: grid;
  gap: 12px;
  margin: 26px 0 0;
  padding: 18px 0 0;
  list-style: none;
  border-top: 2px solid var(--rule);
  color: var(--ink-soft);
}
.trust li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 12px; align-items: start; }
.trust-ico, .secure-ico {
  width: 24px;
  height: 24px;
  margin-top: 1px;
  fill: none;
  stroke: var(--pen);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
/* The tick is drawn on a wider box than the lock, so its line is thickened
   to read at the same weight. */
.trust-ico:has(use[href="#tick"]) { stroke-width: 3.6; }

/* Beside a long slip the timeline stays in view under the sticky nav. */
.start-in > .how { position: sticky; top: 100px; }

/* A family starting again has no timeline beside its slip. */
.start-in.solo { grid-template-columns: minmax(0, 34rem); justify-content: center; }

@media (max-width: 960px) {
  .start-in { grid-template-columns: minmax(0, 1fr); max-width: 36rem; }
  .start-in.solo { grid-template-columns: minmax(0, 1fr); }
  .start-in > .how { position: static; }
}

@media (max-width: 620px) {
  .progress li { flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 8px; font-size: 0.88rem; }
}

/* ---- the plan, printed as a receipt just above the key that starts it:
   what is due today, what the card pays from the trial's last day, and the
   double rule a sum ends on. Numbers stay in plain ink. */

.plan { margin: 20px 0 12px; padding: 14px 0 0; border-top: 2px solid var(--rule); }
.plan h2 { margin: 0 0 4px; font-size: 1.2rem; font-weight: 800; line-height: 1.2; }
.plan-line { color: var(--ink-soft); }
.sum { margin: 12px 0 0; }
.sum > div {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  padding: 9px 0;
  border-top: 1px solid var(--key-line);
}
.sum > div:last-child { border-bottom: 6px double var(--rule); }
.sum dt { font-weight: 700; }
.sum dd { margin: 0 0 0 auto; font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.sum .sum-now dt, .sum .sum-now dd { font-size: 1.3rem; line-height: 1.25; }
.plan-cancel { margin: 12px 0 0; font-weight: 700; }
.plan-remind { margin: 4px 0 0; color: var(--ink-soft); }
.plan + .charges { margin-top: 14px; }
/* On the account step the lede says the plan, so the receipt is the two
   ruled rows straight after the fields, with no heading over them. */
.plan.plan-rows { margin: 4px 0 18px; padding: 0; border-top: 0; }
.plan-rows .sum { margin: 0; }

/* Under the key that goes to Stripe: who takes the card. */
.secure {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 14px 0 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.secure-ico { margin-top: 0; }

/* The welcome page's sum stands on its own between the lede and the text. */
.slip > .sum { margin: 0 0 16px; }

/* The welcome page's next step, above its key. */
.next { margin: 22px 0 10px; font-weight: 700; }

/* A plain button that reads as a link, for the sign-out form on the cover of
   the payment and welcome steps. */
.link-button {
  min-height: 56px;
  padding: 0;
  font: 700 1rem var(--f-print);
  color: var(--on-cover);
  background: none;
  border: 0;
  cursor: pointer;
}
.link-button:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.nav-act form { margin: 0; }

/* ---- what the parent agrees to before Stripe takes the card, in full ink:
   the card now, the charge day, every month until they cancel, and what sets
   the amount. Above the key on the payment step; on the account step under
   its own heading after the key and the secure line, still before Stripe. */

.charges { margin: 0 0 18px; padding: 0 0 0 1.2em; font-size: 0.95rem; line-height: 1.45; }
.charges li { margin: 0 0 5px; }
.charges li::marker { color: var(--pen); }
.charges li:last-child { margin-bottom: 0; }
.agree-list { margin: 22px 0 0; padding: 14px 0 0; border-top: 2px solid var(--rule); }
.agree-list h2 { margin: 0 0 8px; font-size: 1.05rem; font-weight: 800; line-height: 1.25; }
.agree-list .charges { margin: 0; }

/* ------------------------------------------------------------------ the sample emails

   /sample-email is printed onto the grid page like a practice page:
   practice.css brings the column, the ruled headings, the SAMPLE stamp and
   the fold. Each email sits in a phone beside what it shows, and under it on
   a narrow screen. The phone's screen stays white in both themes, because the
   email draws itself in its own light colours, as a mail app shows it. */

.prep.sample-mail { max-width: 64rem; }
.sm-note { max-width: 40em; margin: 16px 0 0; font-weight: 700; }
.sm-sec {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
  grid-template-rows: auto 1fr;
  grid-template-areas: "about phone" "plain phone";
  gap: 0 clamp(32px, 5vw, 64px);
  align-items: start;
}
.sm-about { grid-area: about; }
.sm-about p { max-width: 34em; margin: 22px 0 0; }
.sm-points { max-width: 34em; margin: 14px 0 0; padding-left: 1.2em; }
.sm-points li { margin: 0 0 8px; }
.sm-points li::marker { color: var(--pen); }
.sm-phone {
  grid-area: phone;
  position: relative;
  margin: 0;
  padding: 10px;
  background: var(--bezel);
  border-radius: 30px;
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.1), 0 30px 60px -24px rgba(0, 6, 28, 0.9);
}
.sm-head {
  padding: 20px 18px 12px;
  color: #1b2430;
  background: #ffffff;
  border-bottom: 1px solid #e2dacb;
  border-radius: 23px 23px 0 0;
}
.sm-from { display: block; margin: 0 0 6px; font-weight: 800; }
.sm-subject { display: block; font-size: 0.95rem; line-height: 1.35; color: #56606c; }
.sm-phone .stamp { top: 22px; right: 24px; }
/* The stamp sits on the white screen, so it keeps the day's Teacher Red at night too. */
@media (prefers-color-scheme: dark) { .sm-phone .stamp { color: #cf2e24; border-color: #cf2e24; } }
.sm-frame {
  display: block;
  width: 100%;
  height: 560px;
  border: 0;
  border-radius: 0 0 23px 23px;
  background: #ffffff;
  color-scheme: light;
}
.sm-plain { grid-area: plain; margin-top: 26px; }
.sm-plain pre {
  margin: 0 0 18px;
  font: 0.92rem/1.5 var(--f-print);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.sm-trial { max-width: 40em; margin: 16px 0 0; font-size: 0.95rem; color: var(--ink-soft); }

@media (max-width: 760px) {
  .sm-sec { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "about" "phone" "plain"; }
  .sm-phone { justify-self: center; width: 100%; max-width: 24rem; margin-top: 26px; }
}
