/* Never Too Far, the Begin a Visit postcard. Checkpoint 71, ruling 4,
   verbatim: "are we able to theme this whole page so that it feels like a
   postcard ... questions on the left hand side, and then on the right hand
   side is the calender ... each question should be asked one by one, and
   when the answer is typed, it comes in looking like the script font used
   on the postcard. you can flick back and forth to each question if you
   want to change any of the info."

   This sheet owns page furniture and the postcard shell/message/address
   layout only. The postcard VOCABULARY itself (the harsh block shadow, the
   tape, the wordless stamp, the postmark waves, the hand font) already
   lives in css/site.css as .card / .card .tape / .card .stamp /
   .card .postmark / var(--hand) -- reused here by putting class="card" on
   the postcard <form> and the same tape/stamp/postmark markup inside it,
   not by redefining any of it. picker.js/picker.css are untouched; the
   calendar markup lives in .pc-address as a whole, unedited internally.

   Progressive enhancement: every hiding/collapsing rule below is scoped
   under .js-flow, a class js/begin.js adds only once it has found every
   element it needs. Without that class -- JS disabled, or an error before
   that line runs -- every question, the select and the Other field render
   at once. CORRECTED, checkpoint 87 (2026-08-28): the sentence that used
   to sit here also claimed "the calendar" rendered at once "as one
   complete, working plain form" -- false at the time this was written; the
   calendar's [data-leaf] element was an empty div with nothing in it until
   js/picker.js ran, and the completion control was a live, statically-
   enabled `<a href="/payment">` a no-JS visitor really could click
   through. Both are fixed at their own source now, not here (begin.html
   ships a real Monday-first calendar table in the leaf, and a disabled,
   non-navigating completion control that only an inline script upgrades
   once JS is confirmed running -- see begin.html's checkpoint-87 comment
   and js/picker.js's own header note), so this sentence stops asserting
   what it can't see: a no-JS visitor now gets every question, the select,
   the Other field, a readable calendar and an honestly inert completion
   control -- complete and readable, not a live end-to-end path, since none
   ever existed without JS (there is no server this form submits to). No
   transition is attached to the step
   swap itself (display:none / display:block only) so prefers-reduced-
   motion needs no extra rule for it; the one animated moment, a written
   line settling in, reuses .handnote/.hw from site.css, which already
   carries its own reduced-motion guard. The new hover tilt on the qnav
   arrows (ruling 5, below) gets its own reduced-motion guard here.

   Checkpoint 72 rulings landed in this file: 2 (nothing here -- the font
   was never the CSS's fault, see begin.html's head), 4 (the tape's corner
   swap is a class change in begin.html; .tape.br already exists in
   site.css), 5 (the qnav ink arrows), 6 (the day-kind select/Other field,
   and extra clearance on .pc-address so the enlarged stamp/postmark from
   ruling 7 don't sit on top of the calendar now that the heading and
   radios that used to hold that space are gone), 7 (the stamp/postmark
   size+angle overrides), 8 (the .lead rule is gone with its element), 9
   (.payment and .control-stub are gone with their elements; .pc-footer
   and the new chip cluster take their place).

   Checkpoint 81 rulings landed in this file: 1 (the qnav arrows become
   hand-painted < / > brush marks -- see the comment above .qnav), 2 (the
   progress dots become paint splats -- see the comment above .qdots). */

main.begin{max-width:1260px;margin:0 auto;
  padding:clamp(120px,18vh,168px) clamp(20px,5vw,60px) clamp(90px,12vh,130px)}
.meta-chip.static{position:static;display:inline-block}

/* ── the postcard shell ── */
.postcard-frame{margin:0 0 clamp(70px,10vh,110px)}
.postcard-card{position:relative;display:grid;
  grid-template-columns:minmax(0,1fr) 1px minmax(0,1fr);
  column-gap:clamp(28px,4vw,56px);
  padding:clamp(58px,7vw,88px) clamp(28px,4vw,54px) clamp(34px,4.5vh,46px);
  overflow:visible}
.pc-divider{grid-column:2;width:1px;align-self:stretch;background:rgba(43,42,38,.16)}
.pc-message{grid-column:1;min-width:0}
.pc-address{grid-column:3;min-width:0;
  /* ruling 6+7: the day-kind heading and radios used to hold this much
     clearance below the card's own top padding before the calendar
     started; with them gone, the now-larger stamp/postmark (ruling 7)
     would otherwise sit on top of the calendar's month row. */
  padding-top:clamp(120px,11.5vw,160px)}
.pc-footer{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;
  gap:clamp(14px,2vh,18px);margin-top:clamp(26px,3.6vh,36px);
  padding-top:clamp(26px,3.6vh,36px);border-top:1px solid rgba(43,42,38,.1)}

.pc-message h1{font-weight:300;font-size:clamp(24px,2.6vw,32px);line-height:1.24;
  margin:0 0 clamp(26px,3.6vh,36px);text-wrap:balance}

/* ruling 7: the stamp and postmark, enlarged (~45% up on every site.css
   dimension) and rotated a few degrees as one group so they read hand-
   placed rather than printed dead straight. Overrides the shared .card
   sizing from site.css -- same selector specificity (two classes each
   side), begin.css just loads after site.css, so this wins; site.css
   itself is untouched. The top/right anchors keep the same relative
   offset from the card's corner that site.css already used, just scaled
   up together with the width/height, so the enlarged pair grows inward
   toward the card's centre rather than outward over its edge. */
.postcard-card .stamp{top:clamp(23px,2.6vw,35px);right:clamp(23px,2.6vw,35px);
  width:clamp(75px,7.3vw,96px);transform:rotate(-4deg)}
.postcard-card .postmark{top:clamp(43px,4.4vw,61px);right:clamp(104px,10.7vw,139px);
  width:101px;height:49px;transform:rotate(-4deg)}

/* ── the questions, one at a time ── */
.qletter{display:flex;flex-direction:column;gap:8px}
.qletter:not(:empty){margin:0 0 clamp(18px,2.6vh,26px)}

.field{margin:0 0 clamp(24px,3.4vh,34px)}
.field label{display:block;font-family:var(--sans);font-weight:500;font-size:13px;
  letter-spacing:.04em;color:var(--ink);margin:0 0 8px}
.field input{width:100%;font-family:var(--serif);font-size:16px;color:var(--ink);
  background:none;border:0;border-bottom:1px solid rgba(43,42,38,.3);padding:8px 2px;outline:none}
.field input::placeholder{color:rgba(43,42,38,.42);font-style:italic}
.field .helper{font-family:var(--sans);font-size:12px;color:#6b675f;margin:8px 0 0}

/* the day-kind select: a native control kept in the same quiet underline
   idiom as every other field, no boxed chrome. */
.field-select{position:relative}
.field-select select{width:100%;font-family:var(--serif);font-size:16px;color:var(--ink);
  background:none;border:0;border-bottom:1px solid rgba(43,42,38,.3);
  padding:8px 20px 8px 2px;outline:none;-webkit-appearance:none;appearance:none;
  border-radius:0;cursor:pointer}
.field-select::after{content:"";position:absolute;right:4px;top:9px;width:7px;height:7px;
  border-right:1px solid rgba(43,42,38,.5);border-bottom:1px solid rgba(43,42,38,.5);
  transform:rotate(45deg);pointer-events:none}
.daykind-other{margin:clamp(14px,2vh,20px) 0 0}
.field[data-q="daykind"] .meta-chip.static{margin:clamp(12px,1.6vh,18px) 0 0}
/* plain-form default: always present and visible, per the resilience law
   above -- a no-JS visitor who can't watch the select for a change event
   still sees, and can use, the Other field regardless of what's picked. */
.js-flow .daykind-other{display:none}
.js-flow .daykind-other.is-open{display:block}

/* the live question's own input already writes in the postcard's script
   hand as you type -- "when the answer is typed, it comes in looking like
   the script font used on the postcard" -- the placeholder is switched
   back to the plain instructional voice so the hint never reads as if it
   were already answered. Extends to the day-kind select and its Other
   input the same way (ruling 6). */
.qactive .field input,.qactive .field select{font-family:var(--hand);
  font-size:clamp(19px,1.9vw,23px);padding-bottom:10px}
.qactive .field input::placeholder{font-family:var(--serif);font-size:16px;
  font-style:italic;color:rgba(43,42,38,.42)}

/* one question visible at a time -- JS-only; see the header note above */
.js-flow .qactive .field{display:none}
.js-flow .qactive .field.is-current{display:block}

/* an answered question settling onto the message side: the same written-
   note treatment already used elsewhere on the site (.handnote/.hw, site.css),
   reused as a full-width, left-aligned button so the reader can click back
   into it. white-space is switched from that rule's nowrap (fine for a short
   margin note) to normal, since an answer here can run to a full sentence. */
.qline{display:block;width:100%;text-align:left;background:none;border:0;
  margin:0;padding:3px 4px;cursor:pointer;border-radius:2px}
.qline:hover{background:rgba(43,42,38,.045)}
.qline:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.qletter .handnote{display:block;white-space:normal;line-height:1.5;
  font-size:clamp(17px,1.75vw,21px)}
/* checkpoint 95 ruling 4: a committed answer used to settle in with the
   same clip-path "ink" reveal every other .handnote/.hw on the site uses
   (site.css, ~1.5s) -- this page only, that reveal comes off outright: on
   Enter/next the line appears instantly, fully opaque, no transition. The
   typing itself, inside the still-open input, is untouched (this rule
   only ever reaches a SETTLED .qline, never the live field). Scoped
   under .qletter .qline so index's own handnotes (the chapter margin
   notes, the message-card letter) keep the shared site.css reveal exactly
   as they always have -- this is a page-specific override, not a change
   to the shared rule. Three classes here (.qletter .qline .hw) already
   match or beat both of site.css's own selectors (.handnote .hw at
   (0,2,0); .handnote.written .hw at (0,3,0)) on specificity alone, and
   begin.css loads after site.css regardless, so the tie goes to this rule
   whichever state (written or not) the line is in. clip-path:none replaces
   the inset() clip entirely rather than setting a wide-open inset, so
   there is nothing left mid-transition to catch even a stray reflow;
   transition:none makes the reduced-motion guard on the shared rule moot
   here -- there is no motion to guard against in the first place. */
.qletter .qline .hw,.qletter .qline.written .hw{clip-path:none;transition:none}

.qflow-controls{display:none;align-items:center;justify-content:center;gap:18px;
  margin:clamp(6px,1vh,14px) 0 0}
.js-flow .qflow-controls{display:flex}

/* ruling 5 (checkpoint 72): hand-inked arrows in place of the boxed
   geometric chevrons. No literal "#wob" SVG filter exists anywhere on this
   build (checked -- there is none in site.css, index.html or anywhere
   under src/); the site's real wobble idiom is the unevenly-curved multi-
   point path used by .veil nav .mi svg.strike, which tilts a few degrees
   on hover rather than sliding inside a straight-edged box.

   Checkpoint 81 ruling 1, verbatim: "instead of arrows to toggle through
   each questions, change them to < and >, and mae them feel like they're
   hand painted/hand drawn." The single-weight stroke arrows above are
   replaced (begin.html) with two closed, filled path shapes per button --
   a brush-ribbon idiom: each stroke is the area between two unevenly-
   curved bezier edges (not a uniform stroke-width line), tapering to a
   point at its brush-tip end and landing with a small deliberate offset
   against its partner stroke rather than a mitred vertex, borrowing the
   same "uneven curve, not a crisp mitred line" logic ruling 5 already
   established here, carried from a line-stroke into a filled brush shape.
   No font glyph is used anywhere. .qmark path fill is currentColor, so it
   inherits the button's ink colour (and the disabled paler-ink state)
   exactly as the old stroke arrows did. min-width/min-height keep the
   tap target at 40px even though the painted mark itself is smaller. */
.qnav{width:auto;height:auto;border:0;background:none;color:var(--ink);
  display:grid;place-items:center;cursor:pointer;padding:6px;
  min-width:40px;min-height:40px;
  transition:transform .15s ease,opacity .15s ease}
.qnav svg.qmark{width:20px;height:26px;display:block;overflow:visible}
.qnav svg.qmark path{fill:currentColor}
.qnav:hover{opacity:.72;transform:rotate(-2deg) scale(1.08)}
.qnav.qnext:hover{transform:rotate(2deg) scale(1.08)}
.qnav:focus-visible{outline:2px solid var(--indigo);outline-offset:3px}
.qnav[disabled]{opacity:.28;cursor:not-allowed;transform:none}
@media(prefers-reduced-motion:reduce){.qnav{transition:none}.qnav:hover{transform:none}}

/* the progress dots. Checkpoint 81 ruling 2, verbatim: "the dot looks more
   like a paint splat, which changes in shape as you go toggle through."
   js/begin.js now builds each dot as a small inline SVG splat (a blobby
   closed-bezier centre plus 1-3 tiny satellite droplet circles, nine
   shapes authored once as SPLATS, picked by that step's own index so it's
   fixed per step and differs from its neighbours -- toggling prev/next
   changes which splat reads as current, deterministically, not at random).
   Every dot keeps the same 11x11 SVG box (no layout shift as state
   changes); size and ink are carried entirely by transform:scale and
   fill/opacity so a step's splat shape itself never moves or morphs --
   only which shapes get the "current" treatment. Colour is var(--moss),
   the muted-olive accent already used for .edge-line/.sprig ink marks in
   site.css, not the plain --ink the arrows use, so the splat trail reads
   as its own paint language rather than borrowing the arrows' colour. */
.qdots{display:flex;align-items:center;gap:9px}
.qdots .qdot{display:block;width:11px;height:11px;overflow:visible;
  transform:scale(.55);transform-origin:center;transition:transform .15s ease}
.qdots .qdot .qdot-blob,.qdots .qdot .qdot-drop{fill:none;
  stroke:rgba(43,42,38,.34);stroke-width:1px;
  transition:fill .15s ease,stroke .15s ease,opacity .15s ease}
.qdots .qdot.is-current{transform:scale(1)}
.qdots .qdot.is-current .qdot-blob,.qdots .qdot.is-current .qdot-drop{
  fill:var(--moss);stroke:none;opacity:1}
.qdots .qdot.is-done{transform:scale(.68)}
.qdots .qdot.is-done .qdot-blob,.qdots .qdot.is-done .qdot-drop{
  fill:var(--moss);stroke:none;opacity:.4}
@media(prefers-reduced-motion:reduce){
  .qdots .qdot,.qdots .qdot .qdot-blob,.qdots .qdot .qdot-drop{transition:none}
}

/* ── the address side: the calendar, untouched internally ── */
.pc-address .field-daypicker{margin:0}
.pc-address .picker{background:none;border:0;padding:0}

/* ── the completion button, gated by JS once every question and the day
   are answered ── */
/* checkpoint 73: the black box .btn rule and the flat opacity .is-blocked
   override that used to live here are gone -- css/site.css now owns
   .cta/.btn everywhere (red tape) and its own .btn.is-blocked selector
   already gives the gated state a paler, desaturated tape rather than a
   uniform fade. begin.css loads after site.css, so leaving either rule
   here at the same specificity would silently win the cascade and undo
   both the tape look and its blocked state for this page only. */

.pc-footer-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:8px 14px}

@media(max-width:860px){
  .postcard-card{grid-template-columns:1fr;
    padding:clamp(64px,15vw,84px) clamp(20px,5vw,28px) clamp(28px,5vh,36px)}
  .pc-divider{display:none}
  .pc-message,.pc-address,.pc-footer{grid-column:1}
  .pc-address{margin-top:clamp(30px,6vh,46px);padding-top:clamp(24px,4vh,32px);
    border-top:1px dashed rgba(43,42,38,.18)}
  /* checkpoint 89 fix, 2026-08-28, part of the mobile sweep: the stamp and
     postmark (.postcard-card .stamp/.postmark) are pinned to the CARD's
     own top-right corner, not to either column -- on desktop's real two
     columns that corner sits over .pc-address (the calendar side), clear
     of the heading. Once this same breakpoint collapses the card to one
     stacked column, .pc-message's h1 spans nearly the full card width and
     its single line reaches under the stamp instead: measured at 390
     wide, the sentence rendered start to end at one unbroken 278px-wide
     line, and the stamp's own opaque box (fill:var(--paper), site.css)
     covered its last word, "to see." was in the DOM (copy gate still
     passes, it only reads text, not paint) but not actually visible on
     screen. This margin pushes the heading down clear of the stamp's own
     measured bottom edge (23px top offset + roughly 95px tall at this
     breakpoint's floored clamp values) with a buffer, rather than
     narrowing the heading's width and forcing an unapproved line break in
     wording that renders as one clean line everywhere else. Desktop's own
     .pc-message h1 margin (site.css/begin.css shared rule above) is
     untouched. */
  .pc-message h1{margin-top:66px}
}
