/* ==========================================================================
   Design system v2, the legal and utility family.

   Five routes, loaded after tokens.css and school.css when a page declares
   designSheet: "legal":

     /privacy-policy      long-form policy, ten clauses
     /terms-conditions    26 numbered clauses, sub-clauses, a table, Schedule A
     /gift-voucher-terms  six short clauses
     /sitemap             six link indexes, 230-odd links
     /404                 one route back, plus the site search

   These are documents and indexes, not sales pages. The pack's modules are
   built for copy that has prices, reviews and photographs of a place; a policy
   has clauses and a sitemap has lists. So nothing here is forced into a card
   grid: what the pack contributes to a reading page is the lane marker on
   every section, alternating grounds, the stroked watermark numeral, the
   numbered road line, the paper surface and the closing band, and those are
   the devices used.

   WHY THERE ARE NO NEW CLASS NAMES IN THIS FILE.
   The markup uses only the sm- classes school.css already defines, so every
   class on a legal page has a rule in school.css too, which is what
   check-unstyled-classes.mjs reads. The family's own presentation hangs off
   data-legal* attributes, the same way centre.css hangs off data-centre* and
   school.css hangs the watermark numeral off data-watermark. A second set of
   class names for one family would be a second vocabulary.

   The hooks, all on markup in src/privacy-policy.njk, src/terms-conditions.njk,
   src/gift-voucher-terms.njk, src/sitemap-page.njk and src/404.njk:

     [data-legal="hero"]     the hero, one column, held to a reading measure
     [data-legal="doc"]      a clause section: measure, rhythm, lists, subheads
     [data-legal="note"]     a panel inside the document (the highlighted box)
     [data-legal="table"]    a real data table, the one shape a card loses
     [data-legal="paper"]    the paper surface, I4, the one light surface here
     [data-legal="version"]  the document's own version line
     [data-legal="stops"]    the voucher clauses as the numbered road line
     [data-legal="index"]    a sitemap link index, set in columns
     [data-legal="exits"]    the 404's six routes back
     [data-legal="code"]     the 404's own numeral, at display size
     [data-legal="search"]   the 404's site search, whose ids a script owns
     [data-legal="band"]     the closing call band, on the two pages whose own
                             copy carries a call to make

   Tokens only. Values live in tokens.css, and the spacing scale is named by
   VALUE and skips numbers: --space-13 does not exist, and an undefined var()
   drops the whole declaration silently.

   Every rule that sets a column count sits inside a min-width query, so the
   single-column phone layout in school.css is never out-specified. An
   attribute selector beats a single-class responsive collapse at every width,
   which is how a lessons row once stayed in two columns on a phone.
   ========================================================================== */

/* ---------- 1. The hero ---------- */

/* One column, not the town hero's 1.5fr/0.5fr: there is no pricing aside to
   put in the second track, and an empty track pushes the heading off centre.
   Shorter than a town hero too. A policy is not a landing page and 640px of
   photograph before the first clause is a scroll the reader did not ask for. */
[data-legal="hero"] .sm-hero__grid {
  grid-template-columns: minmax(0, 1fr);
  align-items: end;
  min-height: 440px;
}

[data-legal="hero"] .sm-hero__grid > div { max-width: 44rem; }
[data-legal="hero"] .sm-crumb { padding-top: 0; margin-bottom: var(--space-12); }
[data-legal="hero"] .sm-eyebrow { margin-bottom: var(--space-10); }

/* The heading takes the measure rather than the town hero's 15ch, which breaks
   "Gift Voucher Terms" across three lines. */
[data-legal="hero"] h1 { max-width: 22ch; }

[data-legal="hero"] .sm-lede {
  max-width: 48ch;
  margin-bottom: var(--space-16);
}

/* The copy sits on the near-black end of the ramp, so the photograph is
   pushed right. */
[data-legal="hero"] .sm-hero__photo img { object-position: 76% 38%; }

/* ---------- 2. Reading rhythm ---------- */

/* The measure. 66 characters is the span the pack's body size and line height
   were set for; .sm-prose's shared 72ch ceiling is for a column beside a
   photograph, not for a document someone reads end to end. */
[data-legal="doc"] .sm-prose {
  max-width: 66ch;
  font-size: var(--fs-body-lg);
  line-height: var(--lh-relaxed);
  color: var(--color-text-body);
}
[data-legal="doc"] .sm-prose > p { margin-bottom: var(--space-12); }
[data-legal="doc"] .sm-prose > p:last-child { margin-bottom: 0; }

/* The heading stack: marker, heading, lede. The pack's 24px inside the stack
   and 48px from the stack to the content. */
[data-legal] .sm-section > .sm-wrap > h2 { max-width: 28ch; }

/* Rule 20: a section intro is not flush against the heading above it. */
[data-legal] .sm-lede + * { margin-top: var(--space-24); }
[data-legal="doc"] > .sm-wrap > .sm-lede { margin-bottom: var(--space-24); }

/* A section opener. The live privacy and terms pages set every clause heading
   as h3, with no h2 above them, and that is the markup this project carries
   across rather than renumbers. So the heading that opens a section is an h3
   sitting directly in the wrap, and it takes the pack's section scale: fix
   number one in the pack's own list of what made v1 flat is a section heading
   left at label size. */
[data-legal="doc"] > .sm-wrap > h3,
[data-legal="doc"] > .sm-wrap > h2 {
  max-width: 26ch;
  margin-bottom: var(--space-16);
  font-size: var(--fs-h2-sm);
  line-height: 0.98;
  letter-spacing: -0.035em;
  text-transform: uppercase;
}

/* A clause heading inside running copy. At 22px uppercase it reads as a second
   section opener and breaks the document into pieces, so inside a clause it
   drops the caps and keeps the weight. This is the shape the live pages use:
   a numbered clause heading followed by its paragraphs. */
[data-legal="doc"] .sm-prose h3,
[data-legal="doc"] .sm-prose h4 {
  margin: var(--space-24) 0 var(--space-6);
  font-size: clamp(22px, 2vw, 27px);
  line-height: var(--lh-snug);
  text-transform: none;
  letter-spacing: -0.015em;
  color: var(--color-text);
}

/* A hairline above each clause after the first. Two clauses running together
   on one ground with nothing between them is the pack's eighth flatness fault,
   and inside a section the answer is a rule rather than a change of ground. */
[data-legal="doc"] .sm-prose > h3:not(:first-child) {
  padding-top: var(--space-20);
  border-top: 1px solid var(--rsa-line-08);
}
[data-legal="doc"] .sm-prose h3:first-child,
[data-legal="doc"] .sm-prose h4:first-child { margin-top: 0; }

/* A sub-clause heading. The live terms page sets these as h2 inside an h3
   clause, which is the markup this project carries across rather than
   rewrites; at the shared 50px they would out-shout the clause they sit
   under, so they are set one step below it here. Line height stays under the
   1.08 ceiling the conformance gate holds every h2 to. */
[data-legal="doc"] .sm-prose h2 {
  margin: var(--space-20) 0 var(--space-6);
  font-size: var(--fs-h4);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow-sm);
  color: var(--color-text);
}

[data-legal] .sm-prose strong { color: var(--color-text); font-weight: var(--fw-bold); }
[data-legal] .sm-prose a { text-underline-offset: 3px; }

/* Lists in running copy. A hanging indent, never a grid: a grid puts every
   inline child of an item in its own cell and sets the text one word per
   line. The marker is drawn in the gutter instead. */
[data-legal] .sm-prose ul,
[data-legal] .sm-prose ol {
  margin: 0 0 var(--space-12);
  padding: 0;
  list-style: none;
}
[data-legal] .sm-prose li {
  position: relative;
  margin-bottom: var(--space-6);
  padding-left: var(--space-14);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-text-body);
}
[data-legal] .sm-prose li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 10px;
  height: 2px;
  background: var(--color-accent);
}
[data-legal] .sm-prose li:last-child { margin-bottom: 0; }

/* ---------- 3. A panel inside the document ---------- */

/* The live pages set two blocks apart from the running copy: the cooling-off
   rights on the terms page and the cookie clause on the privacy page. A panel
   gets a hairline and a 5px coloured top rule, never a shadow: shadows in this
   system belong to physical objects. */
[data-legal="note"] {
  margin: var(--space-20) 0;
  padding: var(--pad-panel);
  background: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-top: var(--rule-green-top);
  border-radius: var(--radius-xs);
}
[data-legal="note"] > :last-child { margin-bottom: 0; }

/* The one panel that carries a caution rather than a right takes amber, which
   the pack gives to the honest catch and to nothing else. */
[data-legal="note"][data-tone="caution"] { border-top-color: var(--rsa-amber); }

/* ---------- 4. The table ---------- */

/* The cancellation fee table. A table is the one shape a card grid genuinely
   loses: two notice periods against two fees only mean anything side by side.
   Hairlines rather than cell borders, the head row on Raised. */
[data-legal="table"] {
  width: 100%;
  margin: var(--space-16) 0;
  border-collapse: collapse;
  text-align: left;
}
[data-legal="table"] th,
[data-legal="table"] td {
  padding: var(--space-6) var(--space-10);
  border-bottom: 1px solid var(--rsa-line-10);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
}
[data-legal="table"] thead th {
  background: var(--color-panel-raised);
  border-bottom: 2px solid var(--color-accent);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text);
}
[data-legal="table"] tbody td:first-child {
  font-weight: var(--fw-bold);
  color: var(--color-text);
}
[data-legal="table"] tbody tr:last-child td { border-bottom: 0; }

/* ---------- 5. The paper surface (I4) ---------- */

/* Schedule A is a form to complete and return, so it earns the pack's one
   light surface: a paper-white card, tilted, opened by a red header strip.
   The tilt is the object's own, not a token: the sign tokens are the sign's
   measurements and this is a different object. */
[data-legal="paper"] {
  max-width: 44rem;
  margin: var(--space-24) 0;
  background: var(--rsa-chalk);
  color: var(--rsa-road-black);
  border-radius: var(--radius-md);
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.6);
  transform: rotate(1.2deg);
  overflow: hidden;
}
[data-legal="paper"] > [data-strip] {
  height: 14px;
  background: var(--rsa-red);
}
[data-legal="paper"] > [data-sheet] { padding: var(--space-20) var(--pad-panel); }

/* Everything inside the sheet re-inks: the sheet is the only place on these
   pages where type sits on a light ground, and the shared rules all assume
   dark. */
[data-legal="paper"] h3 {
  margin: 0 0 var(--space-10);
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
  text-transform: none;
  letter-spacing: -0.015em;
  color: var(--rsa-road-black);
}
[data-legal="paper"] p {
  margin: 0 0 var(--space-10);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--rsa-road-black);
}
[data-legal="paper"] p:last-child { margin-bottom: 0; }
[data-legal="paper"] em { color: var(--rsa-road-black); font-style: italic; }
[data-legal="paper"] ul {
  margin: 0 0 var(--space-10);
  padding: 0;
  list-style: none;
}
[data-legal="paper"] li {
  position: relative;
  padding: var(--space-5) 0 var(--space-5) var(--space-16);
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--rsa-road-black);
}
[data-legal="paper"] li:last-child { border-bottom: 0; }
/* A 26px box with a 2px ink border, drawn rather than written, so no tick
   glyph is needed in the text. Ink, not green: Go Green on a chalk ground is
   1.7:1 and Sign Green belongs to road signs and the N plate. */
[data-legal="paper"] li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 18px;
  height: 18px;
  border: 2px solid var(--rsa-road-black);
  border-radius: var(--radius-sm);
}

/* ---------- 6. The version line ---------- */

/* The document's own version, set as a stamp over a hairline rather than as a
   last stray paragraph. */
[data-legal="version"] {
  max-width: 66ch;
  margin: var(--space-24) 0 0;
  padding-top: var(--space-12);
  border-top: 1px solid var(--rsa-line-12);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* ---------- 7. The numbered road line (S4) ---------- */

/* The six voucher clauses are a short numbered sequence, which is the shape
   .sm-stops is for. The shared rule punches the numeral out of the line with
   a border in the page ground, so a stop on a surface section needs the
   surface colour instead. */
[data-legal="stops"] { padding-left: var(--space-28); }
[data-legal="stops"] .sm-stop { margin-bottom: var(--space-24); }
[data-legal="stops"] .sm-stop:last-child { margin-bottom: 0; }
[data-legal="stops"] .sm-stop__num { left: calc(var(--space-28) * -1); }

/* The clause heading inside a stop. The live page sets these as h2, so they
   stay h2: sized to lead a clause rather than a section, and under the 1.08
   line-height ceiling. */
[data-legal="stops"] .sm-stop h2 {
  margin-bottom: var(--space-5);
  font-size: var(--fs-h3);
  line-height: 1.05;
  letter-spacing: -0.015em;
}
[data-legal="stops"] .sm-stop p {
  max-width: 64ch;
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--color-text-body);
}
[data-legal="stops"] .sm-stop p + p { margin-top: var(--space-10); }

.sm-section--surface [data-legal="stops"] .sm-stop__num { border-color: var(--color-panel); }
.sm-section--deep [data-legal="stops"] .sm-stop__num { border-color: var(--color-bg-deep); }

/* ---------- 8. The sitemap indexes ---------- */

/* A sitemap is a link list and it stays one. Not .sm-places: 137 location
   links as 137 bordered cards is a page of boxes, and an auto-fit grid of
   them strands a short last row that no correctness gate sees. Columns are
   set by WIDTH here, so the browser picks the count and the last column is
   never short by a whole row. */
[data-legal="index"] {
  margin: 0;
  padding: 0;
  list-style: none;
  columns: 17rem;
  column-gap: var(--space-20);
}
[data-legal="index"] li {
  margin: 0;
  padding: 0;
  break-inside: avoid;
}
[data-legal="index"] a {
  display: block;
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--rsa-line-08);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--color-text-body);
  text-decoration: none;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
[data-legal="index"] a:hover {
  color: var(--color-text);
  border-bottom-color: var(--color-accent);
}

/* The index that fits on one line per item does not need columns: three legal
   links in two columns leaves a column of one. */
[data-legal="index"][data-cols="1"] { columns: auto; max-width: 30rem; }

/* ---------- 9. The 404's routes back ---------- */

/* The numeral the live page already carries, at the size the pack sets a
   figure that is the content rather than a label. Stroked, so it fills the
   dark without competing with the heading under it. */
[data-legal="code"] {
  display: block;
  margin: 0 0 calc(var(--space-10) * -1);
  font-family: var(--font-display);
  font-size: clamp(96px, 16vw, 200px);
  font-weight: var(--fw-plate);
  line-height: 0.82;
  letter-spacing: var(--ls-tighter);
  color: rgba(255, 255, 255, 0.07);
  pointer-events: none;
  user-select: none;
}
@supports (-webkit-text-stroke: 1px white) {
  [data-legal="code"] {
    color: transparent;
    -webkit-text-stroke: 2px rgba(255, 255, 255, 0.16);
  }
}

/* The site search. Its ids and classes belong to hero-search.js and keep
   their names; only the measure is set here. */
[data-legal="search"] { max-width: 620px; margin-bottom: var(--space-24); }

/* Six routes back. The column count is picked from the item count, not from
   the width: auto-fit would put six cards in four columns and strand two,
   which reads as a fault rather than a grid. Six into three, then six into
   two, then the shared single column on a phone. */
[data-legal="exits"] { gap: var(--space-10); }

[data-legal="exits"] .sm-card {
  gap: var(--space-2);
  padding: var(--space-12) var(--space-14);
  border-left: var(--rule-green);
  text-decoration: none;
  transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-base);
}
[data-legal="exits"] .sm-card:hover {
  background: var(--color-panel-raised);
  border-left-color: var(--rsa-go-green-hover);
}
[data-legal="exits"] .sm-card strong {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-black);
  letter-spacing: -0.01em;
  color: var(--color-text);
}
[data-legal="exits"] .sm-card > span:last-child {
  font-size: var(--fs-small);
  color: var(--color-text-muted);
}

@media (min-width: 600px) {
  [data-legal="exits"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 980px) {
  [data-legal="exits"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- 10. The closing band ---------- */

/* Two of the five pages end on a call the live copy already makes: the privacy
   policy's "Contact us" clause and the 404's "give us a ring". Those take the
   pack's one red band per page, with the white centre line and the 220px L
   plate school.css draws for every family. The other three pages end on the
   footer: a closing band there would need a heading and a line of copy that
   the live page does not have, and writing one is a content change.
   Left aligned, because what sits in it is a clause, not a slogan. */
[data-legal="band"] { text-align: left; }

/* The band's heading is the live clause heading, which on both of these pages
   is an h3. school.css sizes and re-colours .sm-band h2 only, so the h3 takes
   the same treatment here rather than being renumbered to suit a stylesheet. */
[data-legal="band"] h3 {
  max-width: 24ch;
  margin-inline: 0;
  margin-bottom: var(--space-12);
  font-size: var(--fs-h2-sm);
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--color-on-action);
}
[data-legal="band"] h2 { max-width: 24ch; margin-inline: 0; }
[data-legal="band"] .sm-btn-row { justify-content: flex-start; margin-top: var(--space-16); }

/* The pack's band carries a black button and an outlined one, never red on
   red. school.css paints every .sm-btn in the band black at (0,2,0), which
   out-specifies the single-class .sm-btn--ghost and leaves two identical black
   buttons. Restated here at matching specificity so the secondary stays
   outlined. This is a shared fault, not a family one: it is in the report as a
   shared CSS request. */
[data-legal="band"] .sm-btn--ghost {
  background: transparent;
  border-color: var(--rsa-white);
  color: var(--color-on-action);
}
[data-legal="band"] .sm-btn--ghost:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: var(--rsa-white);
}
/* On both of these pages the band holds one sentence, so the sentence is the
   band's scale. At body size a lone line in a full-bleed red band reads as a
   caption of the band rather than its content. */
[data-legal="band"] p {
  max-width: 44ch;
  font-size: clamp(19px, 2vw, 28px);
  font-weight: var(--fw-medium);
  line-height: 1.35;
}
[data-legal="band"] p + ul { margin-top: var(--space-16); }

/* The band's own detail rows: a label and a value, divided by hairlines in
   the band's white rather than boxed. */
[data-legal="band"] ul {
  margin: var(--space-16) 0 0;
  padding: 0;
  list-style: none;
  max-width: 54ch;
}
[data-legal="band"] li {
  padding: var(--space-6) 0;
  border-top: 1px solid var(--rsa-line-25);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--color-on-action);
}
[data-legal="band"] li strong {
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
[data-legal="band"] a {
  color: var(--color-on-action);
  font-weight: var(--fw-bold);
  text-underline-offset: 3px;
}

/* The copy is held clear of the plate by its own measure, not by narrowing the
   wrap. Narrowing .sm-wrap also re-centres it, because the wrap is centred by
   auto margins, and the band's first line then starts 190px right of every
   other section's left edge on the page. Measured at 1440: the widest line in
   the band ends at about 780px and the plate's leading edge is at 1134px, so
   there is nothing to clear. */

/* ---------- 11. Phone rhythm ---------- */

@media (max-width: 768px) {
  [data-legal="hero"] .sm-hero__grid { min-height: 360px; }
  [data-legal="doc"] .sm-prose { font-size: var(--fs-body); }
  /* The tilt costs horizontal room a 390px viewport does not have, and a
     tilted card at that width clips its own corners. */
  [data-legal="paper"] { transform: none; }
  [data-legal="paper"] > [data-sheet] { padding: var(--space-16); }
  [data-legal="stops"] { padding-left: var(--space-24); }
  [data-legal="stops"] .sm-stop__num { left: calc(var(--space-24) * -1); }
  /* Dense link rows get a comfortable row height rather than the 44px button
     floor: an index of 137 links at 44px a row is nine screens. */
  [data-legal="index"] a { padding: var(--space-6) 0; }
}
