/* ══════════════════════════════════════════════════════════════════════════
   Razor-only styles.

   theme.css is a VERBATIM COPY of the React site's stylesheet — 1,282 lines
   that carried over untouched, which is most of why this rebuild was days
   rather than weeks. It is kept byte-identical so the two can be diffed, so
   anything this version needs and that one does not lives here instead.
   ══════════════════════════════════════════════════════════════════════════ */

/* A server-rendered page hides things with the `hidden` attribute rather than
   by not rendering them, and a component that sets `display` beats the
   browser's own [hidden] rule. The basket badge was showing "0" because of
   exactly this. */
[hidden] { display: none !important; }

/* Straight to the content, for anyone on a keyboard or a screen reader.
   Off-screen until focused — and then genuinely visible, not a 1px sliver. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--blue); color: #fff; padding: 12px 18px;
  border-radius: 0 0 10px 0; font-weight: 800; font-size: 0.9rem;
}
.skip:focus { left: 0; }

/* A label a screen reader reads and nobody sees. Not display:none, which
   would take it out of the accessibility tree as well. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The nav group wraps a trigger and its panel so hover can be tracked on the
   pair. It must not disturb the flex row it sits in. */
.nav-grp { display: inline-flex; }

/* The footer headings are <h2> here rather than <h4>: a heading level should
   describe the document, not pick a font size. */
.ftr-h {
  margin: 0 0 16px; font-family: var(--font-head); font-size: 0.95rem;
  font-weight: 800; color: #fff; letter-spacing: 0.01em;
}

/* One category's plans. On the home page these sit inside the tab strip
   below, one shown at a time; each still carries its own link out to the
   full category, which is the route a crawler takes into the catalogue. */
.cat-block { margin-bottom: 0; }
.cat-more { font-size: 0.88rem; font-weight: 800; color: var(--blue); white-space: nowrap; }

.plan-name a { color: inherit; }
.plan-name a:hover { color: var(--blue); }
.plan-savewrap { display: flex; gap: 8px; justify-content: center; margin-bottom: 6px; }

/* The buy box on a plan page. */
.buy-price { display: flex; align-items: baseline; gap: 2px; margin-bottom: 4px; }
.buy-sym { font-family: var(--font-head); font-size: 1.1rem; font-weight: 800; color: var(--navy); }
.buy-amt { font-family: var(--font-head); font-size: 2.4rem; font-weight: 800;
           color: var(--navy); letter-spacing: -0.02em; line-height: 1; }
.buy-per { font-size: 0.85rem; font-weight: 700; color: var(--muted); margin-left: 4px; }
.buy-was { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; font-size: 0.86rem; }
.buy-was s { color: var(--muted); }
.buy-note { margin: 12px 0 0; font-size: 0.78rem; color: var(--muted); text-align: center; }

/* Two columns of features where there is room for them.

   THE ROW GAP IS DELIBERATE AND WAS MISSING. This rule's `gap` shorthand used
   to read `0 24px`, which overrode the 11px `.feat` sets and packed nine
   features into a solid block of text with nothing between the lines. Column
   gap and row gap are now stated separately so neither can be lost by
   shorthand again. */
.feat-2 { display: grid; grid-template-columns: 1fr 1fr;
          column-gap: 30px; row-gap: 13px; }

/* ── The plan page's left column ───────────────────────────────────────────

   Two cards: what the plan includes, and what each tenure costs. Both are the
   catalogue's own data - nothing here is typed prose about a product.

   They exist as two cards rather than one because 47 of the 53 plans have no
   long description, so without the second the column was a short box with a
   tall sticky buy box beside it and a screen's worth of white between them. */
.detail-main { display: grid; gap: 22px; align-content: start; }

/* A heading that is not jammed against the list under it. `h2` is reset to
   margin: 0 site-wide, so the space has to be put back deliberately. */
.spec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding-bottom: 14px; margin-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.spec-head .h-card { font-family: var(--font-head); color: var(--navy); margin: 0; }
.spec-count { font-size: 0.78rem; font-weight: 700; color: var(--muted); white-space: nowrap; }

.spec-list li { align-items: flex-start; }

/* ── The tenure ladder ─────────────────────────────────────────────────────
   A row per rung, each one a link to ?terms=n - the same address the buy
   box's dropdown submits to. The current rung is marked, not just coloured:
   aria-current carries it to a screen reader. */
.term-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

.term-row {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 16px; align-items: baseline;
  padding: 13px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #fff; transition: border-color 0.15s ease, background 0.15s ease;
}
.term-row:hover { border-color: var(--line-2); background: var(--tint-2); }

/* The chosen one. A 1.5px border rather than a thicker one, so the row does
   not change height and the ladder does not shift when you pick another. */
.term-row.on {
  border-color: var(--blue); background: var(--tint);
  box-shadow: inset 0 0 0 1px var(--blue);
}

.term-name { font-weight: 800; color: var(--navy); font-size: 0.94rem;
             display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.term-rate { text-align: right; color: var(--muted); font-size: 0.8rem; white-space: nowrap; }
.term-rate b { color: var(--navy); font-size: 1.02rem; font-weight: 800; }
/* Under the rate and aligned with it, not stretched across the row. The whole
   commitment is the same kind of fact as the monthly figure, so it belongs in
   the same column - across the full width it left a gap beside the term name
   and read like a second, unrelated line. */
.term-total { grid-column: 2; text-align: right; font-size: 0.8rem; color: var(--body); }

.term-foot { margin: 16px 0 0; font-size: 0.78rem; color: var(--muted); }

/* One column on a narrow phone, so the grid-column above has to be released
   or the totals would all try to sit in a column that no longer exists. */
@media (max-width: 480px) {
  .term-row { grid-template-columns: 1fr; }
  .term-rate, .term-total { grid-column: 1; text-align: left; }
}

/* The domain search. The box and the note; the result rows come from
   theme.css, which the React version already defined. */
.dm-box {
  display: flex; align-items: center; gap: 10px; background: #fff;
  border: 1.5px solid var(--line-2); border-radius: var(--pill);
  padding: 8px 8px 8px 22px; box-shadow: var(--shadow-sm); max-width: 620px;
}
.dm-box input {
  flex: 1; min-width: 0; border: 0; outline: none; font-family: var(--font);
  font-size: 1rem; color: var(--navy); background: transparent; padding: 10px 0;
}
.dm-box input::placeholder { color: var(--muted); }
.dm-results { margin: 26px 0 0; display: grid; gap: 8px; }

/* <details>/<summary> instead of a button and a state variable: the FAQ opens
   and closes with no JavaScript at all, and its text is in the HTML whether
   it is open or not — which is what the FAQPage markup asserts. */
.faq-item summary { cursor: pointer; list-style: none; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+"; float: right; font-size: 1.3rem; line-height: 1;
  color: var(--muted); font-weight: 400;
}
.faq-item[open] summary::after { content: "\2212"; color: var(--blue); }
.faq-item[open] summary { color: var(--blue); }

@media (max-width: 640px) {
  .feat-2 { grid-template-columns: 1fr; }
  .dm-box { flex-direction: column; border-radius: var(--radius); padding: 12px; align-items: stretch; }
  .dm-box .btn { width: 100%; }
  .cat-head { flex-direction: column; gap: 6px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   The plan tabs.

   Radio buttons and labels — no JavaScript at all. That is not a stunt: the
   whole reason this site exists is that content behind a click has to be in
   the HTML the server sends, and a tab strip driven by a state variable is
   exactly the pattern that put 61 bytes on every URL of the React site.

   Every panel is rendered. Three of the four are display:none, which a
   crawler reads and a reader reaches with one click, and which survives
   JavaScript being blocked, failing, or not having arrived yet.

   The rules are enumerated to six groups because CSS cannot say "the nth
   checked radio lights the nth label". Six is headroom: the page shows the
   first four categories that have plans.
   ══════════════════════════════════════════════════════════════════════════ */

/* Off-screen rather than display:none — a hidden input is not focusable, and
   these ARE the keyboard interface. Arrow keys move between them for free. */
.ptab-r {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  margin: 0; pointer-events: none;
}

.ptab-panels > .cat-block { display: none; }

.ptab-r:nth-of-type(1):checked ~ .ptab-bar .tab:nth-child(1),
.ptab-r:nth-of-type(2):checked ~ .ptab-bar .tab:nth-child(2),
.ptab-r:nth-of-type(3):checked ~ .ptab-bar .tab:nth-child(3),
.ptab-r:nth-of-type(4):checked ~ .ptab-bar .tab:nth-child(4),
.ptab-r:nth-of-type(5):checked ~ .ptab-bar .tab:nth-child(5),
.ptab-r:nth-of-type(6):checked ~ .ptab-bar .tab:nth-child(6) {
  background: var(--blue); color: #fff; box-shadow: var(--shadow-blue);
}

.ptab-r:nth-of-type(1):checked ~ .ptab-panels > .cat-block:nth-child(1),
.ptab-r:nth-of-type(2):checked ~ .ptab-panels > .cat-block:nth-child(2),
.ptab-r:nth-of-type(3):checked ~ .ptab-panels > .cat-block:nth-child(3),
.ptab-r:nth-of-type(4):checked ~ .ptab-panels > .cat-block:nth-child(4),
.ptab-r:nth-of-type(5):checked ~ .ptab-panels > .cat-block:nth-child(5),
.ptab-r:nth-of-type(6):checked ~ .ptab-panels > .cat-block:nth-child(6) {
  display: block;
}

/* The radio is off-screen, so its focus ring has to be drawn on the label
   standing in for it. Without this the tab strip is unusable by keyboard —
   you would be moving a selection you cannot see. */
.ptab-r:nth-of-type(1):focus-visible ~ .ptab-bar .tab:nth-child(1),
.ptab-r:nth-of-type(2):focus-visible ~ .ptab-bar .tab:nth-child(2),
.ptab-r:nth-of-type(3):focus-visible ~ .ptab-bar .tab:nth-child(3),
.ptab-r:nth-of-type(4):focus-visible ~ .ptab-bar .tab:nth-child(4),
.ptab-r:nth-of-type(5):focus-visible ~ .ptab-bar .tab:nth-child(5),
.ptab-r:nth-of-type(6):focus-visible ~ .ptab-bar .tab:nth-child(6) {
  outline: 2px solid var(--navy); outline-offset: 2px;
}

/* label, not button — the pill styles came from the React version, which
   used one. */
.tabs label.tab { display: inline-block; user-select: none; }

/* The link out to the full category, under the grid rather than beside a
   heading: the pill above already says which category this is. */
.ptab-foot { margin-top: 26px; text-align: center; }

@media (max-width: 640px) {
  /* The strip scrolls sideways on a phone (theme.css already allows it), so
     the pills keep their size instead of being squeezed to nothing. */
  .tabs { margin-bottom: 30px; }
}

/* ── Written page copy and the questions under it ──────────────────────────

   FULL PAGE WIDTH — the same 1400px wrap as the banner and the plan grid
   above. These sections line up with the rest of the page rather than sitting
   in a narrower column inside it.

   That is a deliberate reversal: this was first built as a centred 74ch
   column, on the reasoning that a paragraph running the full 1400px is about
   210 characters a line. It looked wrong — a narrow block of text under a
   full-width plan grid reads as a mistake rather than as a choice. Do not put
   a max-width back here without saying why.

   In site.css rather than theme.css because theme.css is imported by the SPA
   and bundled by Vite, so a rule added there needs a `vite build` and a
   restart before it appears. Nothing in the React basket draws any of this. */
.seo-prose { padding-top: 8px; }

.seo-col, .faq-col { width: 100%; }

.seo-lede {
  font-size: 1.06rem;
  line-height: 1.75;
  color: var(--body);
  margin: 0 0 22px;
}

.seo-prose h2 {
  font-family: var(--font-head);
  font-size: 1.32rem;
  font-weight: 700;
  color: var(--text);
  margin: 34px 0 12px;
  letter-spacing: -0.01em;
}
.seo-prose h2:first-child { margin-top: 0; }

.seo-prose h3 {
  font-family: var(--font-head);
  font-size: 1.08rem;
  font-weight: 700;
  color: var(--text);
  margin: 24px 0 8px;
}

.seo-prose p {
  color: var(--body);
  line-height: 1.75;
  margin: 0 0 14px;
}

.seo-prose ul, .seo-prose ol { margin: 0 0 18px; padding-left: 20px; }

.seo-prose li {
  color: var(--body);
  line-height: 1.7;
  margin-bottom: 9px;
}

.seo-prose li strong { color: var(--text); font-weight: 700; }

/* Underlined, not merely coloured. These sit inside body copy where colour
   alone is the only thing marking them as links, and colour alone is not
   enough for a reader who cannot distinguish it. */
.seo-prose a {
  color: var(--blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.seo-prose a:hover { color: var(--violet); }

/* ── The accordion ─────────────────────────────────────────────────────────

   IT IS THE SITE'S EXISTING FAQ COMPONENT, NOT A SECOND ONE.

   `.faq-item`, `.faq-q` and `.faq-a` are defined in theme.css and were already
   in use by the home page. Redefining them here to restyle the SEO accordion
   restyled the HOME PAGE TOO — its questions lost their 24px of side padding
   and sat hard against the card border, because a blanket `.faq-q { padding:
   17px 2px }` in this file wins on load order wherever those classes appear.

   So this file no longer says anything about them. The card, the padding, the
   radius and the shadow all come from theme.css, and both accordions look the
   same because they ARE the same. Only the container below is new.

   If this accordion ever needs to differ from the home page's, scope the rule
   to `.seo-faq .faq-q` — never restyle the bare class from here. */
.seo-faq { padding-top: 6px; }

/* The container. theme.css spaces the home page's cards with `.faq`, which is
   a narrow centred grid; this one is full width, so it needs its own. */
.faq-list {
  display: grid;
  gap: 12px;
  margin-top: 18px;
}

/* The answers here are wrapped in <p> (the home page's are bare text), and a
   paragraph's default top margin would push the first line away from the
   question it belongs to. */
.faq-list .faq-a p { margin: 0; line-height: 1.75; }

/* Keyboard focus has to be visible; the summary is a real control, and
   theme.css styles it for the mouse only. */
.faq-q:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

@media (max-width: 640px) {
  .seo-prose h2 { font-size: 1.18rem; margin: 26px 0 10px; }
  .seo-lede { font-size: 1rem; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Legal pages — /terms, /refund-policy, /privacy
   ══════════════════════════════════════════════════════════════════════════

   These live HERE and not in theme.css on purpose. theme.css is imported by
   the React basket, so a rule added there is only live after `vite build` and
   a restart; site.css is this Razor site's own sheet and takes effect on
   reload. Nothing on these three pages is shared with the SPA.

   The reading measure comes from `.article` (760px, centred). This adds the
   scaffolding a policy needs that a blog post does not: a clause index, a
   summary table, and headings that can be linked to clause by clause. */

.legal-date { margin: 10px 0 0; font-size: 0.84rem; font-weight: 700;
              color: var(--muted); }

/* A clause the reader arrived at via #anchor must not sit under the sticky
   header. scroll-margin, not padding — it moves the scroll stop, not the
   layout, so the spacing is identical however the reader got there. */
.legal .prose h2 { scroll-margin-top: 96px; }

/* ── The clause index ──────────────────────────────────────────────────── */
.legal-toc { background: var(--tint); border: 1px solid var(--line);
             border-radius: var(--radius); padding: 22px 26px; margin-bottom: 34px; }
.legal-toc h2 { margin: 0 0 12px; font-family: var(--font-head); font-size: 0.82rem;
                font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
                color: var(--muted); }
/* Two columns of a numbered list, counted by CSS: `columns` reflows the items
   so the numbers would restart at the top of column two if they came from the
   <ol> marker. */
.legal-toc ol { list-style: none; counter-reset: c; margin: 0; padding: 0;
                columns: 3; column-gap: 34px; }
/* Three columns at full page width, two on a tablet, one on a phone (below). */
@media (max-width: 1000px) { .legal-toc ol { columns: 2; } }
.legal-toc li { counter-increment: c; break-inside: avoid; margin-bottom: 7px;
                font-size: 0.88rem; }
.legal-toc li::before { content: counter(c) "."; margin-right: 7px; font-weight: 800;
                        color: var(--muted); font-variant-numeric: tabular-nums; }
.legal-toc a { color: var(--body); text-decoration: none; }
.legal-toc a:hover { color: var(--blue); text-decoration: underline; }

/* ── "The short version" ───────────────────────────────────────────────── */
.legal-summary { border: 1px solid var(--line-2); border-radius: var(--radius);
                 padding: 26px; margin-bottom: 38px; box-shadow: var(--shadow-sm); }
.legal-summary h2 { margin: 0 0 16px; font-family: var(--font-head); font-size: 1.15rem;
                    color: var(--navy); }
.legal-summary > p { margin: 14px 0 0; font-size: 0.86rem; }

.legal-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.legal-table th { text-align: left; padding: 0 0 10px; font-size: 0.74rem;
                  font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase;
                  color: var(--muted); border-bottom: 1px solid var(--line); }
.legal-table td { padding: 13px 0; border-bottom: 1px solid var(--line);
                  color: var(--body); vertical-align: top; }
.legal-table td:first-child { padding-right: 20px; color: var(--navy); font-weight: 600; }
.legal-table tr:last-child td { border-bottom: 0; }
.legal-table td .muted { font-weight: 400; }

/* Yes and no carry a word, never colour alone — the answer reads the same to
   somebody who cannot tell the green from the pink. */
.legal-table .ok { color: #00794f; }
.legal-table .no { color: #b3003c; }

/* ── The contact block that closes each document ───────────────────────── */
.legal-contact { background: var(--tint-2); border: 1px solid var(--line);
                 border-radius: var(--radius); padding: 8px 22px; margin: 20px 0 0; }
.legal-contact .fact-row { grid-template-columns: 170px minmax(0, 1fr); }

.legal .prose code { background: var(--tint); border: 1px solid var(--line);
                     border-radius: 5px; padding: 1px 6px; font-size: 0.86em;
                     color: var(--navy); word-break: break-all; }

@media (max-width: 640px) {
  /* One column: two columns of clause titles at 360px is four words a line. */
  .legal-toc { padding: 18px 20px; }
  .legal-toc ol { columns: 1; }
  .legal-summary { padding: 20px; }

  /* The table becomes label-above-answer rows. A two-column table of prose at
     phone width breaks every cell onto four lines. */
  .legal-table thead { display: none; }
  .legal-table, .legal-table tbody, .legal-table tr, .legal-table td { display: block; }
  .legal-table tr { padding: 12px 0; border-bottom: 1px solid var(--line); }
  .legal-table tr:last-child { border-bottom: 0; }
  .legal-table td { padding: 0; border-bottom: 0; }
  .legal-table td:first-child { padding-right: 0; margin-bottom: 4px; }
  .legal-contact { padding: 6px 18px; }
}

