/* Never Too Far, ticket B7 (checkpoint 64, feature 5, item 1): the date picker.
   Home: the booking form page (PAGE_MAP.md section 3, "/begin-a-visit"),
   inside src/pages/begin.html's "Which day?" field.

   Motion law, quoted rather than paraphrased where it matters:
   Creative Direction section 4: "everything behaves like water and ink,
   nothing behaves like software" / "No bounces, no snaps, no hover-tricks"
   / "Slow by design". Operator checkpoint 43, ruling 2, verbatim:
   "ok lets try ink like page turns".

   CHECKPOINT 87 (2026-08-28), "integrate the approved stop-motion calendar
   engine, fix the two HIGH findings, one wave": the checkpoint-84 hand-
   drawn CSS grid (per-cell wobble borders, CSS-content weekday letters and
   numerals, the literal page-turn video overlay) is gone from this file.
   The calendar is now the engine proved out at
   proof/N2F_Stop_Motion_Calendar_Tester_v2.html, built entirely by
   js/picker.js as one SVG (the frame, band lines, weekday headers, date
   numerals and the handwritten month/year line, all in one coordinate
   space, all seed-wobbled) stacked under a transparent interactive layer
   of real <button role="gridcell"> elements sharing the exact same band
   math -- see js/picker.js's own header note for the full reasoning
   (video retirement, Monday-first date math, the aria-hidden-SVG +
   accessible-hit-layer split, the filler-cell fix, the white sheet and its
   re-measured contrast). What this file still owns unmodified: the field
   wrapper rhythm, the hand-painted month/prev/next/today controls
   (.cal-nav/.cal-today, checkpoint 84), the tea-stain blots (.cal-stain),
   and the row of picker-under/picker-state/meta-chip rules below the
   calendar -- all of it "sits naturally with the new engine" per this
   ticket's own brief, so none of it changes here.

   THE SHEET IS WHITE, checkpoint 87: .calendar now paints #FFFFFF (the
   approved tester's own body colour) rather than the old --paper cream, on
   the site's cream ground -- the operator's ruling. See js/picker.js's
   header note for the re-measured numeral contrast on that white
   (14.36:1 full ink; 4.64:1 for the dimmed past-day figure, replacing the
   old ~1.86:1 filed finding).

   CHECKPOINT 88 (2026-08-28), operator's seven rulings on this section:
   ruling 1 -- .calendar's border and box-shadow (the boxed-card treatment
   around the white sheet) are gone below; the sheet itself stays #FFFFFF
   (untouched -- no ruling here asks for a different ground, and that
   colour is load-bearing for the checkpoint-87 contrast figures above).
   ruling 2 -- .cal-today (the painted-dot "go to current month" control)
   is removed outright, begin.html and js/picker.js both; its rules are
   deleted below rather than left dead.
   ruling 3 -- .cal-month's CSS-generated numeral badge (::before) is gone;
   js/picker.js now draws the handwritten month/year as its own small
   aria-hidden SVG inside that span (buildMonthYearSVG()), so .cal-month
   only needs to be a flex-centred slot for it now, not a text-styled
   element in its own right.
   ruling 4 -- .calendar's padding is cut back sharply below so .cal-sheet
   (still width:auto, still filling its parent per checkpoint 87) reaches
   the full width of its column instead of a padded-down fraction of it --
   paired with js/picker.js's Y1 change (640 -> 720, more of the viewBox's
   height actually used by the grid rows), the whole sheet and everything
   drawn on it scale up together. Measured at 1440/390: see the
   checkpoint-88 QA note.
   ruling 5 -- .picker-under (the two static lines beneath the calendar)
   is deleted below, unused now that begin.html no longer renders any
   element with that class; .picker-state's own rule stays (still a live
   region for the "soon" feedback, now usually empty -- :empty{margin:0}
   already handled that). The new heading takes .cal-heading, added below.
   ruling 6 -- the selected-day mark is now a hand-scribbled SVG path
   (js/picker.js), not a plain <ellipse>; .pen-scribble below carries its
   one-time stroke-dashoffset reveal and reduced-motion guard. The "soon"
   ring's stroke-width is trimmed slightly (js/picker.js) so it reads
   quieter next to the bolder scribble -- no CSS change needed for that,
   it's a literal SVG attribute picker.js writes per-mark like the rest.
   ruling 7 -- .cal-stain and its three variants are deleted below; this
   page was their only user (grepped: nothing else under src/ references
   them), so the dead weight goes with the markup rather than staying as
   an orphaned rule. */

/* checkpoint 87: the old --n2f-dur-page-turn / --n2f-dur-settle /
   --n2f-ease-settle tokens (and the --n2f-wobble-a/b/c per-cell border
   images they sat alongside) are gone outright, not zeroed -- grepped the
   whole src/ tree, nothing outside this file and js/picker.js ever
   referenced them. The engine is a hard cut: one redraw, one
   resting-position shift, applied synchronously (js/picker.js -- no CSS
   transition, no timer anywhere in the motion path), so there is no
   duration/easing token left to carry. */

/* ── the field wrapper, matching begin.html's .field rhythm ── */
.field-daypicker .field-label-text{display:block;font-family:var(--sans);font-weight:500;
  font-size:13px;letter-spacing:.04em;color:var(--ink);margin:0 0 8px}

.picker{border:1px solid rgba(43,42,38,.14);padding:clamp(20px,3vw,30px);background:var(--raised)}
.picker-heading{font-family:var(--serif);font-weight:300;font-size:clamp(18px,2vw,22px);
  margin:0 0 clamp(16px,2.4vh,22px);color:var(--ink)}

/* checkpoint 88 ruling 5: corpus entry N-0804, "Choose your date", renders
   here, in the hand face, above the calendar -- the calendar's own
   accessible name (#daypicker-label, begin.html) is untouched and stays
   sr-only, so this heading is additive, not a replacement for it. Sized
   to read as a clear heading (bigger than the handwritten month/year line
   ruling 3 places inside the calendar below it, per the ticket). */
.cal-heading{font-family:var(--hand);font-weight:400;text-align:center;
  font-size:clamp(30px,3.6vw,46px);line-height:1.15;color:var(--ink);
  margin:0 0 clamp(18px,2.4vh,24px)}

/* ── the calendar itself: a torn-out paper page, not a boxed panel ──
   Checkpoint 87: white (#FFFFFF), per the approved tester and the
   operator's ruling -- see the file header note. Checkpoint 88 ruling 1:
   the bordered, shadowed "card" that used to frame this white sheet is
   gone -- no border, no box-shadow -- matching "everything behaves like
   water and ink, nothing behaves like software" even more plainly than
   before; the sheet's own SVG-drawn ink frame (js/picker.js
   buildSheetSVG) is the only edge it needs. Ruling 4: padding is cut back
   to a thin breathing margin rather than the old generous card inset, so
   .cal-sheet (still width:auto, filling this box) reaches the column's
   full width instead of a padded-down fraction of it. */
.calendar{margin:0 0 clamp(22px,3.2vh,30px);background:#FFFFFF;
  padding:clamp(4px,.6vw,8px) clamp(2px,.4vw,6px) clamp(6px,.8vw,10px)}
.cal-head{display:flex;align-items:center;gap:8px;margin:0 0 12px}

/* the prev/next controls: checkpoint 81 ruling 1's hand-painted bracket
   idiom (already landed for the postcard's own qprev/qnext, begin.css
   .qnav) carried onto the calendar's prev/next controls, per checkpoint
   84's "restyle them to painted marks consistent with the begin page's
   new painted brackets". Same recipe: two closed, filled brush-ribbon
   paths per bracket (not a font glyph, not a single-weight stroke),
   fill:currentColor so it inherits ink/disabled colour exactly like
   .qnav does, and the same hover tilt. Unmodified by checkpoint 87
   ("painted month controls from P26 may stay"). Checkpoint 88 ruling 2:
   the third control this row used to carry, .cal-today (a painted-dot
   "jump to current month" button), is removed outright per the
   operator's order -- begin.html no longer renders it, js/picker.js no
   longer looks it up or binds a handler to it, and its rules (which used
   to sit here as ", .cal-today" / ", .cal-today:focus-visible" and the
   two .cal-today-mark rules below) are deleted rather than left dead. */
.cal-nav{width:auto;height:auto;border:0;background:none;color:var(--ink);
  display:grid;place-items:center;cursor:pointer;padding:5px;
  min-width:32px;min-height:32px;transition:transform .15s ease,opacity .15s ease}
.cal-nav svg.cal-mark{width:14px;height:19px;display:block;overflow:visible}
.cal-nav svg.cal-mark path{fill:currentColor}
.cal-nav:hover{opacity:.72;transform:rotate(-2deg) scale(1.08)}
.cal-nav[data-nav="next"]:hover{transform:rotate(2deg) scale(1.08)}
.cal-nav:focus-visible{outline:2px solid var(--indigo);outline-offset:3px}
@media(prefers-reduced-motion:reduce){.cal-nav{transition:none}.cal-nav:hover{transform:none}}

/* checkpoint 88 ruling 3: this used to be a text-styled element carrying
   a CSS-generated numeral badge (::before: attr(data-m) " / " attr(data-y),
   picker.js set data-m/data-y). Both are gone -- js/picker.js now builds
   the handwritten month/year as its own small aria-hidden SVG
   (buildMonthYearSVG()) and drops it straight into this span, so .cal-month
   only needs to centre whatever child it's given, at a width that keeps
   the label legible without crowding the two brackets either side of it. */
.cal-month{flex:1;display:flex;justify-content:center;align-items:center;min-width:0}
.cal-month-svg{display:block;width:100%;max-width:260px;height:auto;overflow:visible}
.cal-month-svg text{font-family:var(--hand)}

/* .cal-grid-frame no longer positions anything (checkpoint 88 ruling 7
   removed the .cal-stain blots it used to anchor); kept as a plain
   wrapper around .cal-stage rather than unwrapped, since begin.html's own
   [data-stage] lookup (js/picker.js) targets the child, not this div, and
   removing an unreferenced ancestor is no part of any of the seven
   rulings. position:relative left in place -- harmless, and cheaper to
   leave than to prove nothing else will ever need it. */
.cal-grid-frame{position:relative}

/* ── checkpoint 87: the stop-motion sheet ──
   .cal-sheet is the whole physical page -- the ONLY element the
   resting-position shift (translate + rotate, js/picker.js) ever moves,
   so the decorative SVG and the interactive hit layer always travel
   together and stay aligned. aspect-ratio locks it to the SVG's own
   viewBox (1000 x 740) so every [data-leaf] child's percentage-based
   position lines up with the SVG's coordinate space at any viewport
   width -- no JS measuring, no resize listener. */
.cal-sheet{position:relative;aspect-ratio:1000/740;margin:0 auto}
.cal-svg{display:block;width:100%;height:100%}
/* the whole sheet's ink (frame, band lines, weekday headers, numerals, the
   month/year line, and the per-day marks) is one aria-hidden SVG --
   meta-register calendar furniture, never corpus copy, never announced to
   assistive tech; see js/picker.js's header note. Font only, here: every
   colour is written literal per <text>/<path> in js/picker.js itself (a
   var() on an SVG presentation attribute is too fragile to trust -- see
   that file's own note), so nothing about ink colour lives in this rule. */
.cal-svg text{font-family:var(--hand)}

/* the REAL accessible grid: transparent, positioned by the exact same
   band math the SVG uses (js/picker.js buildHitLayer()), stacked over it.
   Each .day is a native <button role="gridcell"> with no visible content
   of its own -- the numeral a sighted visitor reads is the SVG's, the
   accessible name a screen-reader visitor gets is this button's
   aria-label (the long form: weekday, month, day, year). */
.cal-hit-layer{position:absolute;inset:0}
.day{position:absolute;margin:0;padding:0;border:0;background:none;
  cursor:pointer;-webkit-tap-highlight-color:transparent}
.day.is-empty{cursor:default;pointer-events:none}
.day.is-past{cursor:not-allowed}
.day:focus-visible{outline:2px dashed var(--indigo);outline-offset:2px;z-index:2;border-radius:2px}

/* checkpoint 88 ruling 6: the selected-day mark, a hand-scribbled circle
   (js/picker.js buildScribblePath()) in place of the old plain wobbled
   ellipse. pathLength="1" on that path (set in the markup itself) lets
   the reveal below work in plain 0..1 units regardless of the path's
   actual drawn length -- no runtime getTotalLength() measuring needed.
   The reveal itself is a CSS transition (declarative, not a timer): the
   path is born with stroke-dashoffset:1 (fully hidden) and js/picker.js
   flips it to 0 on the very next frame via requestAnimationFrame, which
   sequences the transition's start/end states and is not the kind of
   "timer" the engine's zero-timer law is about (that law retired a
   setTimeout coordinating "wait for a video clip to finish playing" --
   an unrelated, since-removed concern). Instant under reduced motion:
   js/picker.js never gives the path the dash attributes or this class at
   all in that case, so there's nothing to transition from. */
.pen-scribble{transition:stroke-dashoffset .3s ease-out}
@media(prefers-reduced-motion:reduce){.pen-scribble{transition:none}}

/* ── checkpoint 87: the no-JS fallback, begin.html's static [data-leaf]
   table (HIGH FIX 1 -- the cp71 no-JS resilience law). Plain and legible
   on purpose ("no wobble needed for the static fallback" -- this ticket's
   own brief): js/picker.js replaces this table outright with the live
   .cal-sheet the instant it boots, so nothing here needs to survive
   contact with the real engine's look, only be readable without it. */
.cal-fallback{width:100%;border-collapse:collapse;table-layout:fixed;
  background:#FFFFFF;font-family:var(--serif);color:var(--ink)}
/* checkpoint 95, HIGH FIX B, RETIRED: the <caption> this rule styled named
   a literal month ("August 2026", begin.html) -- honest the day it
   shipped, wrong every day after, for as long as no-JS visitor ever saw
   this table with no live engine to replace it (a filed finding). The
   caption element itself is gone from begin.html's markup (there is no
   honest month-specific caption to put in its place, and the table no
   longer carries date rows a caption would even be labelling); this rule
   is dead weight left behind by that removal. Retired, not deleted, per
   house practice.
.cal-fallback caption{font-family:var(--sans);font-weight:500;font-size:12px;
  letter-spacing:.1em;text-transform:uppercase;color:#4a4740;text-align:center;
  margin:0 0 10px}
*/
.cal-fallback th,.cal-fallback td{padding:8px 2px;text-align:center;
  font-size:14px;border:1px solid rgba(43,42,38,.12)}
.cal-fallback th{font-family:var(--sans);font-weight:500;font-size:11px;
  letter-spacing:.08em;color:#4a4740}
/* checkpoint 95, HIGH FIX B: the honest no-JS fallback line, replacing the
   removed month-specific <caption> and date <tbody> -- see begin.html's
   own comment at [data-leaf] for the full reasoning. Plain, quiet,
   meta-register furniture (qa/render_exclusions.txt carries the dated
   allowlist entry), matching the same understated register as
   .cal-fallback's own header cells rather than reading as a warning. */
.cal-noscript{margin:10px 0 0;font-family:var(--sans);font-size:12px;
  letter-spacing:.04em;color:#4a4740;text-align:center}

/* checkpoint 88 ruling 7: the tea-stain blots (.cal-stain and its three
   variants, checkpoint 84) are removed outright, CSS and markup both --
   this page was their only user (grepped the whole src/ tree to confirm),
   so nothing is left dead behind them. */

/* ── the twelve-month sentence slot, checkpoint 84: "the calendar
   carries their slot with an honest chip until he rules" ── the slot
   renders, empty, ready to take a corpus id once the operator proofs one
   of the twelve (picker.js sets data-sentence-id from a per-month table
   it never fills with text); the chip is the only visible content here,
   and class="meta-chip" is already exempt from the F1 render-copy gate
   (qa/render_exclusions.txt CLASS SKIP), the same mechanism every other
   build-annotation chip on this page already uses. No sentence text is
   authored by this ticket or any ticket before the operator's proof. */
.cal-sentence{margin:0 0 clamp(14px,2vh,18px)}
.cal-sentence-line{margin:0;min-height:1.3em;font-family:var(--hand);
  font-size:clamp(15px,1.6vw,18px);color:var(--ink)}
.cal-sentence-line:empty{margin:0}

/* checkpoint 88 ruling 5: .picker-under (the two static lines that used to
   sit below the calendar) is deleted -- begin.html no longer has an
   element with that class, so the rule would be dead weight left behind.
   .picker-state stays: it's still a live aria-live region for the "soon"
   feedback (js/picker.js STATE_TEXT.soon), just usually empty at rest now
   that STATE_TEXT.empty is '' -- :empty{margin:0} already handled that
   case before this ticket, no change needed to the rule itself. */
.picker-state{font-family:var(--sans);font-size:12.5px;color:var(--verm);margin:0 0 14px;
  min-height:1.3em}
.picker-state:empty{margin:0}

/* the meta-chip is already exempt from the rendered-copy gate (F1 skips
   class="meta-chip" outright, docs/copy render_exclusions.txt section on
   CLASS SKIP). Reused here, unmodified, for the required notes that the
   marked-day set and the twelve month sentences both await the
   operator's ruling -- build annotations authored by these tickets, not
   corpus copy, exactly like the page's existing "CONFIRM-AND-CHANGE
   CONTROL" and "PAYMENT FACTS" chips. */
.picker-note{display:block;margin:4px 0 0}

@media(max-width:520px){
  .cal-fallback th,.cal-fallback td{padding:6px 1px;font-size:12px}
}
