/* smartlocksuk.com — national editorial brand.
 *
 * Third stylesheet in this project, and deliberately a third visual world.
 * smartlockpro is charcoal + brass with Archivo/IBM Plex; installer is navy
 * + indigo with Bricolage/Instrument Sans. Both are grotesques on a dark
 * ink; both open with a headline-over-image hero and a call to action.
 *
 * This one is a publication: a serif for everything a reader reads, a mono
 * for every piece of editorial furniture (eyebrows, dates, bylines, labels),
 * and no hero at all — the home page opens with the lead piece and a dated
 * index, the way a masthead-led publication does. The difference from its
 * siblings is structural rather than a repaint, which is the whole point;
 * the installer site's first version proved that a new palette over the same
 * DOM still reads as the same site.
 *
 * NEVER load this alongside smartlockpro.css or installer.css. All three
 * define overlapping class names with different values on purpose.
 *
 * Fonts are self-hosted latin subsets (74KB total) — no third-party request,
 * so no visitor IP reaches a font CDN and the privacy policy stays true.
 * Licences ship alongside them in ../fonts/.
 */

@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader-400.db13f5205bae.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader-400i.cf5a6f6430ab.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "NewsreaderDisplay";
  src: url("../fonts/newsreader-700.3ca3a4e0f579.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "SpaceMono";
  src: url("../fonts/spacemono-400.cd11216c5176.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #1b1714;
  --ink-soft: #5f574e;
  --ink-faint: #8b8177;
  --paper: #fdfcfa;
  --panel: #f2eee7;
  --line: #ddd5c9;
  --line-strong: #b9ac9b;
  /* Plum-wine. Chosen to be non-semantic: on a reviews site the accent must
     not read as "good", or it collides with the verdict colours below. */
  --accent: #6d2544;
  --accent-deep: #521a33;
  /* Semantic, and used ONLY inside a verdict. Kept away from the accent so
     "what works / what doesn't" reads instantly without relying on colour
     alone — each list also carries its own glyph. */
  --good: #2c6146;
  --bad: #9a3b23;

  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --display: "NewsreaderDisplay", "Newsreader", Georgia, serif;
  --mono: "SpaceMono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  --measure: 42rem; /* the reading column; ~72 characters at 1.125rem */
  --page: 1180px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
a:hover {
  text-decoration-color: var(--accent);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 50;
  background: var(--ink);
  color: var(--paper);
  padding: 0.6rem 1rem;
}

/* Container. Only ever sets horizontal padding — see the .wrap gotcha in
   CLAUDE.md, where a shorthand `padding` on a container element silently
   zeroed the gutters and went unnoticed on desktop for weeks. Anything that
   needs vertical space uses a longhand property. */
.page {
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: 24px;
}
.narrow {
  max-width: var(--measure);
}

/* Editorial furniture: mono, small, letterspaced. Every label, date, byline
   and section marker on the site uses this, which is what makes the type
   system legible as a system rather than as decoration. */
.eyebrow,
.meta,
.kicker {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ---------- masthead ---------- */

.masthead {
  border-bottom: 1px solid var(--ink);
  background: var(--paper);
}
.masthead-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.4rem 1rem;
}
.wordmark {
  font-family: var(--display);
  font-size: clamp(1.6rem, 4.5vw, 2.3rem);
  letter-spacing: -0.02em;
  line-height: 1;
  text-decoration: none;
}
.wordmark span {
  color: var(--accent);
}
.masthead-strap {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: right;
  max-width: 20ch;
  line-height: 1.5;
}

/* Sections sit under a rule as a plain horizontal run — not a sticky bar,
   not a dropdown. A publication's navigation is its contents list. */
.sections {
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  padding-block: 0.7rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.sections a {
  text-decoration: none;
  color: var(--ink-soft);
  padding-block: 0.15rem;
  border-bottom: 2px solid transparent;
}
.sections a:hover,
.sections a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

/* ---------- home index ---------- */

.lead-standfirst {
  max-width: 46rem;
  font-size: 1.18rem;
  color: var(--ink-soft);
  margin: 0;
  padding-block: 2rem 1.8rem;
}

/* Full-bleed lead. v1 had no image at all and the fold was 79% blank paper;
   the picture is what fills it. Deliberately edge-to-edge, with the caption
   re-entering the page grid so the type still aligns with everything below. */
.leadfig {
  margin: 0;
  position: relative;
  background: var(--ink);
  /* Grid-stacked rather than relying on the image being taller than the
     caption. With both children in the same cell the figure's height is the
     LARGER of the two, so an overlong headline can never push the caption out
     of the top of the frame — which is what it did on narrow screens, landing
     it on top of the paragraph above. Tuning a breakpoint only moved where
     that broke. */
  display: grid;
}
.leadfig > img,
.leadfig > .leadcap {
  grid-area: 1 / 1;
}
/* The bottom gradient alone is not enough: the headline sits around 55% of
   the frame height, where that gradient has already faded out, so legibility
   depended entirely on what the photograph happened to be doing there. This
   adds a left-to-right scrim under the text column. */
.leadfig::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to right,
    rgba(14, 10, 8, 0.72) 0%,
    rgba(14, 10, 8, 0.5) 42%,
    rgba(14, 10, 8, 0.12) 72%,
    rgba(14, 10, 8, 0) 100%
  );
}
.leadcap {
  z-index: 1;
}

.leadfig > img {
  width: 100%;
  height: clamp(260px, 46vw, 520px);
  object-fit: cover;
  display: block;
}
.leadcap {
  font-family: var(--serif);
  align-self: end;
  padding-block: 6rem 2rem;
  color: var(--paper);
  /* Three stops, not two: a straight linear gradient leaves a visible band
     where it meets the photograph. */
  background: linear-gradient(
    to top,
    rgba(14, 10, 8, 0.93) 12%,
    rgba(14, 10, 8, 0.62) 46%,
    rgba(14, 10, 8, 0) 100%
  );
}
/* On a narrow screen the overlay does not work: the caption is taller than
   the image (kicker + three-line headline + four-line standfirst + byline is
   ~300px against a 260px photo), so an absolutely-positioned caption anchored
   to the bottom spills out of the top of the figure and lands on top of the
   paragraph above it. Below this width it stacks under the photo instead,
   which is also simply more legible. */
@media (max-width: 959px) {
  .leadfig::after {
    display: none;
  }
  /* Below this width the caption drops out of the shared grid cell and sits
     under the photograph on a solid ground — more legible, and it removes the
     overlay's contrast dependency on whatever the photo is doing. */
  .leadfig {
    display: block;
  }
  .leadcap {
    background: var(--ink);
    padding-block: 1.5rem 1.7rem;
  }
  .lead-title {
    max-width: none;
  }
}

/* No photograph on the lead piece — the caption still needs a ground to sit
   on, or white text lands on white paper. */
.leadcap-flat {
  position: static;
  background: var(--ink);
  padding-block: 2.6rem;
}
.kick {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #e8b6c9;
  border-left: 3px solid #b0446e;
  padding-left: 0.55rem;
  margin: 0 0 0.75rem;
}
.lead-title {
  font-family: var(--display);
  font-size: clamp(2.1rem, 5.4vw, 3.4rem);
  line-height: 1.03;
  letter-spacing: -0.026em;
  margin: 0 0 0.6rem;
  max-width: 18ch;
  text-wrap: balance;
}
.lead-title a {
  text-decoration: none;
  color: inherit;
}
.lead-title a:hover {
  text-decoration: underline;
  text-decoration-color: #b0446e;
  text-underline-offset: 0.12em;
}
.lead-sub {
  font-size: 1.1rem;
  color: #e6ded6;
  margin: 0 0 0.7rem;
  max-width: 52ch;
}
.lead-by {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #b6aca3;
  margin: 0;
}
/* The flat variant sits on paper-coloured text over ink, same as the overlay,
   so nothing extra is needed — but the no-image homepage headline should not
   run the full width. */
.leadcap-flat .lead-title {
  max-width: 20ch;
}

/* Dated contents. A ruled list with thumbnails — not cards. Twelve identical
   white cards is the pattern the smartlockpro redesign existed to fix, but
   three bare paragraphs was the opposite mistake. */
.index {
  padding-block: 2.4rem 3.4rem;
}
.index-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 0.55rem;
  margin-bottom: 0.3rem;
}
.index-head h2 {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
  margin: 0;
}
.index-head a {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
}
.index-head a:hover {
  text-decoration: underline;
}
.index-item {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0.2rem 1.1rem;
  padding-block: 1.15rem;
  border-bottom: 1px solid var(--line);
  align-items: start;
}
@media (min-width: 760px) {
  .index-item {
    grid-template-columns: 9rem 1fr 7rem;
    gap: 0.3rem 1.7rem;
  }
}
.index-thumb {
  display: block;
  grid-row: span 2;
  background: var(--panel);
}
@media (min-width: 760px) {
  .index-thumb {
    grid-row: auto;
  }
}
.index-thumb img {
  width: 100%;
  aspect-ratio: 10 / 7;
  object-fit: cover;
  display: block;
}
.index-thumb-empty {
  aspect-ratio: 10 / 7;
  border: 1px solid var(--line);
}
.sect {
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.3rem;
}
.index-item h3 {
  font-family: var(--display);
  font-size: 1.3rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
  margin: 0;
}
.index-item h3 a {
  text-decoration: none;
}
.index-item h3 a:hover {
  color: var(--accent);
}
.index-sub {
  margin: 0.3rem 0 0;
  color: var(--ink-soft);
  font-size: 0.98rem;
}
.index-when {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0.35rem 0 0;
}
@media (min-width: 760px) {
  .index-when {
    text-align: right;
    margin-top: 0.15rem;
  }
}

/* ---------- article ---------- */

.article-head {
  padding-block: 2.6rem 1.4rem;
  border-bottom: 1px solid var(--line);
}
.article-head h1 {
  font-family: var(--display);
  font-size: clamp(2.1rem, 5.6vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: -0.024em;
  margin: 0.6rem 0 0.8rem;
  text-wrap: balance;
}
.article-standfirst {
  font-size: 1.24rem;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0 0 1.4rem;
  max-width: 40rem;
}
.byline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.2rem;
  align-items: baseline;
}
.byline .sep {
  color: var(--line-strong);
}

.article-figure {
  margin: 0;
  padding-block: 1.6rem 0;
}
.article-figure img {
  width: 100%;
  border: 1px solid var(--line);
}
/* Scoped to article figures. As a bare `figcaption` this also matched the
   full-bleed lead caption on the home page — which is a <figcaption> — so the
   headline's standfirst inherited the mono face and rendered as code. Third
   time in this stylesheet that a generic selector has reached into a
   component; see the .verdict-head and .wrap notes in CLAUDE.md. */
.article-figure figcaption {
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--ink-faint);
  padding-top: 0.55rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.8rem;
}
figcaption .credit {
  color: var(--line-strong);
}

/* Article pages get their own narrower container, centred. Previously the
   prose was capped at --measure inside the full 1180px page container, so
   every article sat hard against the left edge with a dead third to the
   right — a side-note column with no side notes in it. */
.reading {
  max-width: 42rem;
  margin-inline: auto;
}

.article-body {
  padding-block: 1.8rem 3rem;
}
.article-body p {
  margin: 0 0 1.3rem;
}
.article-body h2 {
  font-family: var(--display);
  font-size: 1.65rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin: 2.4rem 0 0.9rem;
}
.article-body ul,
.article-body ol {
  margin: 0 0 1.3rem;
  padding-left: 1.2rem;
}
.article-body li {
  margin-bottom: 0.5rem;
}
.article-body a {
  text-decoration-color: var(--accent);
}
.article-body strong {
  font-weight: 400;
  font-family: var(--display);
}

/* ---------- editorial blocks ---------- */

.keypoints {
  max-width: var(--measure);
  background: var(--panel);
  border-left: 3px solid var(--accent);
  padding: 1.2rem 1.4rem;
  margin: 0 0 1.8rem;
}
.keypoints h2 {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.7rem;
  font-weight: 400;
}
.keypoints ul {
  margin: 0;
  padding-left: 1.05rem;
}
.keypoints li {
  margin-bottom: 0.45rem;
  font-size: 1.02rem;
}
.keypoints li:last-child {
  margin-bottom: 0;
}

/* The verdict breaks the measure deliberately — it's the thing a reader
   scrolls to find, so it should not look like more prose. */
.verdict {
  max-width: 46rem;
  border: 1px solid var(--ink);
  margin: 2.2rem 0;
}
/* Scoped to .verdict deliberately. As a bare `.verdict-head` this loses to
   `.article-body h2` — same specificity trap as the `.masthead .wrap` bug in
   CLAUDE.md: a descendant selector for generic prose reaches into a
   component and wins. It showed as a 38px white strip above the black bar,
   which looks like a padding mistake and isn't. */
.verdict .verdict-head {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.5rem 1.2rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.verdict-body {
  padding: 1.3rem 1.2rem;
}
.verdict-body > p:first-child {
  margin-top: 0;
}
.verdict-best {
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--ink-soft);
  border-top: 1px solid var(--line);
  padding-top: 0.9rem;
  margin-top: 0.4rem;
}
.verdict-best b {
  display: block;
  margin-bottom: 0.15rem;
  color: var(--ink);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
}
.verdict-cols {
  display: grid;
  gap: 1.4rem;
  border-top: 1px solid var(--line);
  padding: 1.2rem;
}
@media (min-width: 700px) {
  .verdict-cols {
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
  }
}
.verdict-cols h3 {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 400;
  margin: 0 0 0.6rem;
}
.verdict-good h3 {
  color: var(--good);
}
.verdict-bad h3 {
  color: var(--bad);
}
.verdict-cols ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.98rem;
}
.verdict-cols li {
  padding-left: 1.15rem;
  position: relative;
  margin-bottom: 0.5rem;
  line-height: 1.5;
}
/* A glyph as well as a colour: the two lists must still be distinguishable
   in monochrome, or to anyone who can't separate the two hues. */
.verdict-good li::before {
  content: "+";
  position: absolute;
  left: 0;
  color: var(--good);
  font-family: var(--mono);
}
.verdict-bad li::before {
  content: "−";
  position: absolute;
  left: 0;
  color: var(--bad);
  font-family: var(--mono);
}

.spectable {
  max-width: 46rem;
  margin: 2rem 0;
}
.spectable h2 {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
  margin: 0 0 0.5rem;
}
/* Tables get their own scroll container so the page body never scrolls
   sideways on a narrow screen. */
.spectable-scroll {
  overflow-x: auto;
}
.spectable table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.98rem;
  font-variant-numeric: tabular-nums;
}
.spectable th,
.spectable td {
  text-align: left;
  padding: 0.6rem 0.8rem 0.6rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.spectable th {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 400;
  width: 40%;
  white-space: nowrap;
}

.pullquote {
  max-width: 42rem;
  margin: 2.2rem 0;
  padding-left: 1.4rem;
  border-left: 3px solid var(--accent);
}
.pullquote p {
  font-family: var(--display);
  font-size: 1.5rem;
  line-height: 1.28;
  letter-spacing: -0.015em;
  margin: 0;
}
.pullquote cite {
  display: block;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-style: normal;
  padding-top: 0.7rem;
}

.disclosure {
  max-width: var(--measure);
  border: 1px dashed var(--line-strong);
  padding: 0.9rem 1.1rem;
  margin: 2rem 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
  background: var(--panel);
}
.disclosure p {
  margin: 0;
}
.disclosure p + p {
  margin-top: 0.6rem;
}

.howwerate {
  max-width: var(--measure);
  border-top: 1px solid var(--line);
  margin-top: 2.4rem;
  padding-top: 1.1rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.howwerate b {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink);
  font-weight: 400;
  display: block;
  margin-bottom: 0.4rem;
}

/* ---------- section index ---------- */

.section-head {
  padding-block: 2.6rem 1.4rem;
  border-bottom: 1px solid var(--ink);
}
.section-head h1 {
  font-family: var(--display);
  font-size: clamp(1.9rem, 5vw, 2.8rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0.5rem 0 0.6rem;
}
.section-head p {
  max-width: 42rem;
  color: var(--ink-soft);
  margin: 0;
}

/* ---------- static pages + forms ---------- */

.prose {
  max-width: var(--measure);
  padding-block: 2.4rem 3rem;
}
.prose h1 {
  font-family: var(--display);
  font-size: clamp(1.9rem, 5vw, 2.7rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 0.8rem;
}
.prose h2 {
  font-family: var(--display);
  font-size: 1.5rem;
  margin: 2.2rem 0 0.7rem;
}
.prose p {
  margin: 0 0 1.2rem;
}
.prose ul {
  padding-left: 1.2rem;
  margin: 0 0 1.2rem;
}
.prose li {
  margin-bottom: 0.5rem;
}

.field {
  margin-bottom: 1.2rem;
}
.field label {
  display: block;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
}
.input {
  width: 100%;
  font-family: var(--serif);
  font-size: 1rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line-strong);
  border-radius: 0;
  padding: 0.65rem 0.7rem;
}
.input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 0;
  border-color: var(--accent);
}
textarea.input {
  min-height: 9rem;
  line-height: 1.55;
}
.btn {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
  padding: 0.75rem 1.5rem;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
}
.errorlist {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  color: var(--bad);
  font-size: 0.9rem;
}
.form-success {
  border-left: 3px solid var(--good);
  background: var(--panel);
  padding: 1rem 1.2rem;
  margin-bottom: 1.4rem;
}

/* ---------- footer ---------- */

.foot {
  border-top: 1px solid var(--ink);
  margin-top: 2rem;
  padding-block: 2rem 3rem;
}
.foot-grid {
  display: grid;
  gap: 1.6rem;
}
@media (min-width: 760px) {
  .foot-grid {
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 3rem;
  }
}
.foot h2 {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
  margin: 0 0 0.7rem;
}
.foot ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.98rem;
}
.foot li {
  margin-bottom: 0.4rem;
}
.foot-about {
  font-size: 0.98rem;
  color: var(--ink-soft);
  max-width: 34ch;
  margin: 0;
}
.foot-note {
  border-top: 1px solid var(--line);
  margin-top: 1.8rem;
  padding-top: 1.1rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.7;
  color: var(--ink-faint);
}

/* ---------- cookie banner ---------- */

.cookie {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--ink);
  color: var(--paper);
  padding: 1rem 1.2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 1.6rem;
  align-items: center;
  justify-content: space-between;
}
.cookie p {
  margin: 0;
  font-size: 0.95rem;
  max-width: 58ch;
}
.cookie a {
  color: var(--paper);
}
.cookie .row {
  display: flex;
  gap: 0.7rem;
}
.cookie .btn {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
  padding: 0.55rem 1.1rem;
}
.cookie .btn-outline {
  background: transparent;
  color: var(--paper);
  border-color: var(--line-strong);
}
.cookie.hidden {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
