/* ==========================================================================
   ODETTE GOMES · THE WORKROOM
   Design system for the Lisbon landing page. Standalone — this page does not
   load css/style.css, so nothing here can affect the Cape Town portfolio.

   The idea is unchanged from v1: the page should look drafted, not
   published. Calico and pattern paper, graphite, one thread-red marking
   line, measurements in the margin.

   What changed in v2 (22 October 2026) is the voice. The studio's own
   typeface, Glacial Indifference, now carries the brand at every size —
   display, labels, buttons, table heads, the footer — and a single reading
   serif carries the prose beneath it. Three hired families became one owned
   face and one companion. See the header of section 03.

   See site-internal/strategy/design-system.md for the tokens, the component
   specs and the reasoning behind replacing the old system.

   Contents
   01. Fonts
   02. Tokens
   03. Reset & base
   04. Typography
   05. Layout primitives
   06. Annotation (the signature component)
   07. Buttons & links
   08. Header
   09. Hero
   10. Marque
   11. Comparison
   12. Figures
   13. Steps
   14. Credentials & testimonials
   15. Tariff
   16. Disclosure (FAQ)
   17. Form
   18. Footer
   19. Reduced motion & print
   ========================================================================== */

/* 01. Fonts -------------------------------------------------------------- */
/* Glacial Indifference (Alfredo Marco Pradil, SIL Open Font License 1.1 —
   the licence travels with the files in fonts/OFL.txt) is served from this
   origin rather than a font host: it is the brand's own face, it is two
   small files, and a self-hosted font cannot be delayed by a third party on
   the critical path. The reading serif still comes from Google Fonts, which
   is the one external request the page makes. */
@font-face {
  font-family: "Glacial Indifference";
  src: url("../fonts/glacial-indifference-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Glacial Indifference";
  src: url("../fonts/glacial-indifference-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* 02. Tokens ------------------------------------------------------------- */
:root {
  /* Colour — a workroom, not a gallery. Every pair below is contrast-checked
     in strategy/design-system.md; --ink-3 and --thread are the two that sit
     closest to the AA floor, so neither may be lightened. */
  --paper:      #f3f0e9;
  --paper-2:    #e9e5db;
  --paper-3:    #dfdace;
  --ink:        #1b1a17;
  --ink-2:      #3d3a34;
  --ink-3:      #6b665c;          /* 5.0:1 on paper */
  --line:       #cfc8b8;
  --line-faint: rgba(27, 26, 23, 0.10);

  --thread:         #9a2f26;      /* 6.5:1 on paper */
  --thread-dark:    #7c241d;
  --thread-on-dark: #e0786b;      /* 5.8:1 on ink. --thread is 2.3:1 there. */

  --on-ink:      #f3f0e9;
  --on-ink-2:    rgba(243, 240, 233, 0.68);
  --on-ink-line: rgba(243, 240, 233, 0.18);

  /* Type — see section 04 for what each one is for.
     Glacial Indifference carries no euro sign and no middle dot. Nothing set
     in --display may contain either: the euro lives only in the tariff and
     the price sentence, both of which are set in --text, which has it. The
     middle dot in the annotations falls through to the next face in the
     stack, where it is a dot either way. */
  --display: "Glacial Indifference", "Avenir Next", "Futura", "Century Gothic", "Trebuchet MS", sans-serif;
  --text:    "Newsreader", "Iowan Old Style", "Palatino", Georgia, serif;
  --annot:   var(--display);

  --fs-d1:    clamp(2.5rem, 1.6rem + 3.6vw, 4.5rem);
  --fs-d2:    clamp(1.875rem, 1.45rem + 1.7vw, 2.75rem);
  --fs-d3:    clamp(1.125rem, 1.05rem + 0.4vw, 1.375rem);
  --fs-lead:  clamp(1.125rem, 1.05rem + 0.5vw, 1.375rem);
  --fs-body:  1.125rem;
  --fs-small: 0.9375rem;
  --fs-micro: 0.75rem;

  /* Tracking. A geometric sans needs the opposite treatment at each end of
     the scale: opened right up in small caps so the counters do not close,
     and pulled in at display sizes so a headline reads as one object. */
  --track-display: -0.022em;
  --track-caps:     0.14em;

  /* Space — one scale, no ad-hoc values at call sites. */
  --s1: 0.25rem;  --s2: 0.5rem;   --s3: 0.75rem;  --s4: 1rem;
  --s5: 1.5rem;   --s6: 2rem;     --s7: 3rem;     --s8: 4rem;
  --s9: 6rem;     --s10: 8rem;

  --gutter:      clamp(1.25rem, 5vw, 3rem);
  --wrap:        1200px;
  --wrap-narrow: 680px;
  --section-y:   clamp(4rem, 9vw, 8rem);
  --annot-col:   200px;
  --header-h:    72px;

  --hair: 1px solid var(--line);
  --dur:  180ms;
  --ease: cubic-bezier(0.2, 0, 0, 1);
}

/* 03. Reset & base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--text);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.62;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  color: var(--ink);
}
p  { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
img { max-width: 100%; height: auto; display: block; }
figure { margin: 0; }
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
strong { font-weight: 600; color: var(--ink); }

/* The focus ring is never removed and never restyled away. It is 2px of ink
   at a 3px offset on every interactive thing on the page. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.on-ink :focus-visible { outline-color: var(--on-ink); }

::selection { background: var(--thread); color: var(--paper); }

.skip-link {
  position: fixed;
  top: 0; left: 0;
  z-index: 300;
  padding: var(--s3) var(--s5);
  background: var(--ink);
  color: var(--on-ink);
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  transform: translateY(-110%);
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 04. Typography --------------------------------------------------------- */
/* Two faces, and the division between them is the whole system.

   GLACIAL INDIFFERENCE is the studio's own typeface and it holds everything
   that names a thing: the wordmark, every heading, every label, the buttons,
   the table heads, the footer. It is geometric, wide and even-coloured, so
   it takes a large size without going heavy and a small one without going
   fussy. It has a regular and a bold and no italic, which is exactly why the
   companion below is a serif.

   NEWSREADER reads. It carries the body, the lead paragraphs, the answers,
   the price figures — and the italic, which is the one thing Glacial cannot
   set. An emphasis inside a Glacial headline therefore arrives as a serif
   italic, and that contrast is the page's only ornament. It is used in place
   of colour, not alongside it. */

.d1, .d2 { letter-spacing: var(--track-display); text-wrap: balance; }
.d1 { font-size: var(--fs-d1); line-height: 1.04; max-width: 17ch; }
.d2 { font-size: var(--fs-d2); line-height: 1.08; max-width: 20ch; }
.d3 {
  font-size: var(--fs-d3);
  line-height: 1.22;
  letter-spacing: -0.01em;
  font-weight: 400;
}

/* The emphasis. Serif, italic, ink — never also red. One signal is a signal;
   two at once is a shout. */
.d1 em, .d2 em, .d3 em {
  font-family: var(--text);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 44ch;
}
.prose { max-width: 62ch; }
.small { font-size: var(--fs-small); }
.muted { color: var(--ink-3); }
em { font-style: italic; }

.on-ink { background: var(--ink); color: var(--on-ink-2); }
.on-ink h1, .on-ink h2, .on-ink h3 { color: var(--on-ink); }
.on-ink .lead { color: var(--on-ink); }
.on-ink .muted { color: var(--on-ink-2); }

/* 05. Layout primitives -------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: var(--section-y); }
.section + .section { border-top: var(--hair); }
.on-ink + .section, .section + .on-ink { border-top: 0; }

/* A full-width grid with named lines, used where something has to run to the
   edge of the screen while its neighbour stays on the text column. Built
   from percentages rather than 100vw, so a scrollbar cannot push it wide. */
.bleed-grid {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wrap-start] min(calc(var(--wrap) - var(--gutter) * 2), calc(100% - var(--gutter) * 2))
    [wrap-end] minmax(var(--gutter), 1fr)
    [full-end];
}
.bleed-grid > * { grid-column: wrap; }

/* The annotation column. At desktop widths a section's eyebrow and margin
   note sit in a narrow left column, ruled off from the content — notes
   written down the side of a pattern. Below 900px it collapses above the
   content and the rule disappears. This is what makes the page look
   drafted rather than typeset. */
.spread { display: grid; gap: var(--s5); }
@media (min-width: 900px) {
  .spread {
    grid-template-columns: var(--annot-col) minmax(0, 1fr);
    gap: var(--s8);
  }
  .spread__aside {
    border-right: var(--hair);
    padding-right: var(--s6);
    height: 100%;
  }
  .on-ink .spread__aside { border-right-color: var(--on-ink-line); }
}
.spread__note { margin-top: var(--s4); font-size: var(--fs-small); color: var(--ink-3); }
.on-ink .spread__note { color: var(--on-ink-2); }

.stack-5 > * + * { margin-top: var(--s5); }
.stack-6 > * + * { margin-top: var(--s6); }

/* 06. Annotation --------------------------------------------------------- */
/* The eyebrow: a 24px thread rule and a line of letterspaced caps. In v1
   these were set in a monospace, which read as a terminal. In the studio's
   own geometric caps they read as the head of a letterhead, which is what
   they are. */
.annot {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: 0;
  font-family: var(--annot);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}
.annot::before {
  content: "";
  flex: 0 0 auto;
  width: 24px;
  height: 1px;
  background: var(--thread);
}
.annot--bare::before { display: none; }
.annot--thread { color: var(--thread); }
.on-ink .annot { color: var(--on-ink-2); }
.on-ink .annot::before { background: var(--thread-on-dark); }
.on-ink .annot--thread { color: var(--thread-on-dark); }

/* 07. Buttons & links ---------------------------------------------------- */
/* The primary action is ink, not thread. In v1 the red filled the buttons,
   which put the loudest colour on the page in four or five places at once
   and left the marking line with nothing of its own. Ink on calico is the
   higher contrast of the two (15.4:1) and the quieter of the two, and it
   gives the thread back its single job: a line drawn in the margin. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s6);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--ink);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { background: var(--thread); border-color: var(--thread); }
.btn:active { transform: translateY(1px); }

.btn--secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.btn--secondary:hover { background: transparent; border-color: var(--ink); color: var(--ink); }

/* On ink the fill inverts, because an ink button on an ink ground is a hole. */
.on-ink .btn { background: var(--on-ink); color: var(--ink); border-color: var(--on-ink); }
.on-ink .btn:hover { background: var(--thread-on-dark); border-color: var(--thread-on-dark); color: var(--ink); }
.on-ink .btn--secondary { background: transparent; color: var(--on-ink); border-color: var(--on-ink-line); }
.on-ink .btn--secondary:hover { background: transparent; border-color: var(--on-ink); color: var(--on-ink); }

.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }

/* Tertiary: a text link that sits in the flow of a paragraph or under a
   block. The underline is always there — a link that only underlines on
   hover is a link you cannot see. */
.btn--quiet {
  background: none;
  border: 0;
  padding: 0;
  min-height: 0;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: none;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.3em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--line);
}
.btn--quiet:hover { color: var(--thread); text-decoration-color: currentColor; background: none; }

.actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
@media (max-width: 599px) {
  .actions { flex-direction: column; align-items: stretch; }
  .actions .btn { width: 100%; }
}

/* 08. Header ------------------------------------------------------------- */
/* A landing page leaks visitors through every link that is not the one
   action, so this header carries no navigation: the mark, where the atelier
   is, and the consultation button. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--paper);
  border-bottom: var(--hair);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  min-height: var(--header-h);
}

/* One SVG painted with currentColor through a CSS mask, so the mark takes
   the colour of whatever it sits on without a second file. Carried over
   from the old system — it was the right technique. */
.mark {
  display: block;
  background-color: currentColor;
  -webkit-mask: url("../img/wordmark.svg") no-repeat center / contain;
          mask: url("../img/wordmark.svg") no-repeat center / contain;
  aspect-ratio: 1529 / 406;
  height: 30px;
  color: var(--ink);
}
@media (min-width: 600px) { .mark { height: 36px; } }

.site-header__right { display: flex; align-items: center; gap: var(--s5); }
.site-header__where { display: none; }
@media (min-width: 760px) { .site-header__where { display: flex; } }

/* "Book a consultation" does not fit beside the wordmark on a phone, and a
   header button that wraps to two lines is the loudest thing on screen. */
.site-header .btn { white-space: nowrap; }
.cta-long { display: none; }
@media (min-width: 560px) {
  .cta-long  { display: inline; }
  .cta-short { display: none; }
}

/* 09. Hero --------------------------------------------------------------- */
/* Still not a full-bleed photograph: the proposition keeps the text column
   and the photograph takes the right half and runs off the edge of the
   screen. The first screen carries an argument, and the argument has a
   garment standing next to it. */
.hero { padding-block: var(--s7) var(--s8); }
@media (min-width: 900px) { .hero { padding-block: var(--s9) var(--s10); } }

.hero__grid { display: grid; gap: var(--s7); align-items: center; }
/* The first track is the page's own left margin, written the way .wrap
   computes it, so the headline starts on the same vertical as every section
   below it. The last track has no margin after it, which is what lets the
   photograph run off the right edge. 100% is the grid's width rather than
   100vw, so a scrollbar cannot widen it. Where the viewport is narrower than
   --wrap the calc goes negative, minmax falls back to its minimum, and the
   track is a plain gutter — again matching .wrap. */
@media (min-width: 900px) {
  .hero__grid {
    grid-template-columns:
      minmax(var(--gutter), calc((100% - var(--wrap)) / 2 + var(--gutter)))
      minmax(0, 1fr)
      minmax(0, 1.08fr);
    column-gap: 0;
    row-gap: 0;
    padding-inline: 0;
    max-width: none;
  }
  .hero__copy   { grid-column: 2; padding-right: var(--s9); }
  .hero__figure { grid-column: 3; }
}

.hero__title { margin-block: var(--s5) var(--s5); }

/* The three facts under the fold-line. Plain, checkable, and the only proof
   on the page until there are testimonials to put here instead. */
.hero__facts {
  list-style: none;
  margin: var(--s6) 0 0;
  padding: var(--s5) 0 0;
  border-top: var(--hair);
  display: grid;
  gap: var(--s3);
}
.hero__facts li {
  display: flex;
  gap: var(--s3);
  font-size: var(--fs-small);
  color: var(--ink-3);
}
.hero__facts li::before {
  content: "";
  flex: 0 0 auto;
  width: 7px; height: 7px;
  margin-top: 0.55em;
  border: 1px solid var(--thread);
}

/* 10. Marque ------------------------------------------------------------- */
/* One statement, alone between the work and the mechanics. The page is a
   long argument and it needs somewhere to stop and say the thing plainly.
   Nothing else is allowed in this section. */
.marque { padding-block: var(--section-y); text-align: center; }
.marque__line {
  font-family: var(--display);
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 3.25rem);
  line-height: 1.12;
  letter-spacing: var(--track-display);
  text-wrap: balance;
  color: var(--ink);
  margin: 0 auto;
  max-width: 22ch;
}
.marque__line em {
  font-family: var(--text);
  font-style: italic;
  letter-spacing: 0;
}
.marque__rule {
  display: block;
  width: 24px;
  height: 1px;
  background: var(--thread);
  margin: 0 auto var(--s6);
}

/* 11. Comparison --------------------------------------------------------- */
/* The argument of the page: what a boutique does, and what happens here.
   Two columns, ruled apart, so the difference is structural and not a claim. */
.compare { display: grid; gap: 0; border-top: var(--hair); }
@media (min-width: 760px) { .compare { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.compare__col { padding: var(--s6) 0; border-bottom: var(--hair); }
@media (min-width: 760px) {
  .compare__col { padding: var(--s6) var(--s6) var(--s6) 0; }
  .compare__col + .compare__col { padding-left: var(--s6); padding-right: 0; border-left: var(--hair); }
}
.compare__head {
  margin-block: var(--s4) var(--s5);
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}
.compare--ours .compare__head { color: var(--thread); }
.compare__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); }
.compare__list li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s3); font-size: var(--fs-small); }
.compare__list li::before { content: "—"; color: var(--ink-3); font-family: var(--annot); }
.compare--ours .compare__list li::before { content: "+"; color: var(--thread); }
.compare--ours .compare__list li { color: var(--ink-2); }
.compare--theirs .compare__list li { color: var(--ink-3); }

/* 12. Figures ------------------------------------------------------------ */
/* A photograph, flush on the page, with its caption in the studio's caps
   underneath. v1 sat each one on a pattern-paper mat; at six to a grid the
   mats read as six cheap frames and took 24px off the width of every
   garment. The photographs are the most persuasive thing here and they get
   the whole column.

   Full colour, always: the old system greyscaled every garment until hover,
   which hid the work and showed nothing at all on a touch screen. */
.fig { display: grid; gap: var(--s4); }
.fig__mat { background: none; padding: 0; }
.fig__mat img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; background: var(--paper-2); }
.fig--wide .fig__mat img { aspect-ratio: 4 / 3; }
.fig__cap {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: var(--s3);
  border-top: var(--hair);
}

.fig-grid { display: grid; gap: var(--s6); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .fig-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7); } }

/* The hero photograph runs to the edge of the screen, so it is taller than
   it is in the grid and its caption sits inside the text column. */
.hero__figure .fig__mat img { aspect-ratio: 4 / 5; }
@media (min-width: 900px) {
  .hero__figure .fig__mat img { aspect-ratio: 5 / 6; }
}

/* 13. Steps -------------------------------------------------------------- */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps__item {
  display: grid;
  gap: var(--s2) var(--s5);
  padding-block: var(--s5);
  border-top: var(--hair);
}
.steps__item:first-child { border-top: 0; padding-top: 0; }
@media (min-width: 700px) {
  .steps__item { grid-template-columns: 3rem minmax(0, 1fr) auto; align-items: baseline; }
}
.on-ink .steps__item { border-top-color: var(--on-ink-line); }

.steps__n {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  color: var(--thread);
  font-variant-numeric: tabular-nums;
}
.on-ink .steps__n { color: var(--thread-on-dark); }
.steps__body { max-width: 46ch; }
.steps__body p { margin: var(--s3) 0 0; font-size: var(--fs-small); color: var(--ink-3); }
.on-ink .steps__body p { color: var(--on-ink-2); }
.steps__meta {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
.on-ink .steps__meta { color: var(--on-ink-2); }

/* 14. Credentials & testimonials ----------------------------------------- */
.creds { display: grid; gap: 0; border-top: var(--hair); }
@media (min-width: 700px) { .creds { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.creds__item { padding: var(--s5) 0; border-bottom: var(--hair); }
@media (min-width: 700px) {
  .creds__item { padding-inline: var(--s5); border-left: var(--hair); }
  .creds__item:first-child { padding-left: 0; border-left: 0; }
  .creds__item:last-child { padding-right: 0; }
}
.creds__value {
  display: block;
  font-family: var(--display);
  font-size: var(--fs-d2);
  line-height: 1;
  letter-spacing: var(--track-display);
  color: var(--ink);
}
.creds__label { display: block; margin-top: var(--s3); font-size: var(--fs-small); color: var(--ink-3); max-width: 28ch; }

/* The testimonial surface. Markup for it is in lisbon.html, commented out
   until there are real quotations to put in it — a page should never carry
   an invented one. Never render fewer than two: a single testimonial reads
   as the only one there is. */
.quotes { display: grid; gap: var(--s6); }
@media (min-width: 900px) { .quotes { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.quote { display: grid; gap: var(--s4); align-content: start; padding-top: var(--s5); border-top: var(--hair); }
.quote::before { content: ""; width: 24px; height: 1px; background: var(--thread); }
.quote__text {
  font-family: var(--text);
  font-style: italic;
  font-size: var(--fs-d3);
  line-height: 1.4;
  color: var(--ink);
  max-width: 34ch;
  margin: 0;
}
.quote__by {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* 15. Tariff ------------------------------------------------------------- */
/* The one place a price appears on this page. A figure repeated across a
   page reads as anxiety about the number; stated once, in full, with what
   it includes, it reads as confidence.

   v1 set it on a raised panel. It is now ruled off on the page itself, like
   a published tariff rather than a pricing card — the whole argument of the
   page is that the figures are simply stated, and a box around them says
   the opposite. */
.tariff-panel {
  background: none;
  padding: 0;
  border-top: 2px solid var(--ink);
  padding-top: var(--s6);
}
@media (min-width: 700px) { .tariff-panel { padding-top: var(--s7); } }

/* Capped at a measure rather than run to the width of the column. A row
   where the name and the figure sit a thousand pixels apart is a row you
   read twice — this is a tariff, and a tariff is read the way a menu is. */
.tariff { width: 100%; max-width: 40rem; border-collapse: collapse; margin-top: var(--s6); }
.tariff caption { text-align: left; }
.tariff thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

.tariff__group th {
  padding: var(--s7) 0 var(--s3);
  font-family: var(--annot);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-align: left;
  color: var(--ink-3);
  border-bottom: var(--hair);
}
.tariff tbody:first-of-type .tariff__group th { padding-top: 0; }

.tariff tbody tr:not(.tariff__group) th,
.tariff td {
  padding-block: var(--s3);
  border-bottom: 1px solid var(--line-faint);
  vertical-align: baseline;
}
.tariff tbody tr:not(.tariff__group) th {
  text-align: left;
  font-family: var(--text);
  font-weight: 400;
  color: var(--ink-2);
  padding-right: var(--s4);
}
/* The price column is the accent's second permitted use. Set in the reading
   serif, which is also the only face on the page with a euro sign, and
   tabular so the figures stack. Never stacked under the label, even on a
   phone: a name and a number fit side by side at any width, and stacking
   would double the length of the list for nothing. */
.tariff td {
  text-align: right;
  white-space: nowrap;
  font-family: var(--text);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--thread);
}
.tariff__sub { display: block; font-size: var(--fs-micro); color: var(--ink-3); font-style: italic; }

.tariff__terms {
  max-width: 40rem;              /* the table's measure, so the rules line up */
  margin-top: var(--s7);
  padding-top: var(--s5);
  border-top: var(--hair);
  display: grid;
  gap: var(--s5);
}
@media (min-width: 760px) { .tariff__terms { grid-template-columns: minmax(0, 1fr) auto; align-items: end; } }
.tariff__terms p { font-size: var(--fs-small); color: var(--ink-3); max-width: 60ch; }

/* 16. Disclosure --------------------------------------------------------- */
/* <details>, not a scripted accordion: it opens without JavaScript, it is
   already in the accessibility tree, and find-in-page opens a closed match. */
.faq { border-top: var(--hair); }
.faq__item { border-bottom: var(--hair); }
.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s5);
  padding-block: var(--s5);
  font-family: var(--display);
  font-size: var(--fs-d3);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--thread); }

/* A plus that becomes a minus, drawn in CSS so it inherits the text colour
   and needs no icon file. */
.faq__q::after {
  content: "";
  flex: 0 0 auto;
  width: 12px; height: 12px;
  margin-top: 0.45em;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1px 100% no-repeat;
  transition: transform var(--dur) var(--ease);
}
/* Hide the horizontal bar, not the vertical one: the quarter-turn is what
   lays the surviving stroke down flat into a minus. Hiding the vertical bar
   instead leaves the horizontal one standing on end. */
.faq__item[open] .faq__q::after { background-size: 0 1px, 1px 100%; transform: rotate(90deg); }
.faq__a { padding-bottom: var(--s5); max-width: 60ch; font-size: var(--fs-small); }

/* 17. Form --------------------------------------------------------------- */
.form { display: grid; gap: var(--s5); }
.form-row { display: grid; gap: var(--s5); }
@media (min-width: 620px) { .form-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.field { display: grid; gap: var(--s2); }
/* The label is always visible. A placeholder is not a label: it disappears
   the moment someone types, and the field loses its name. */
.field__label {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--on-ink-2);
}
.field__req { color: var(--thread-on-dark); }
.field__hint { font-size: var(--fs-small); color: var(--on-ink-2); }

.input, .select, .textarea {
  width: 100%;
  min-height: 52px;
  padding: var(--s3) 0;
  font-family: var(--text);
  font-size: var(--fs-body);
  font-weight: 400;
  color: var(--on-ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--on-ink-line);
  border-radius: 0;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.input:hover, .select:hover, .textarea:hover { border-bottom-color: rgba(243, 240, 233, 0.45); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-bottom-color: var(--on-ink);
  box-shadow: 0 1px 0 0 var(--on-ink);
}
.textarea { min-height: 128px; resize: vertical; line-height: 1.6; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23f3f0e9' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.25rem center;
  background-size: 12px 8px;
  padding-right: var(--s6);
  cursor: pointer;
}
.select option { color: var(--ink); background: var(--paper); }
::placeholder { color: rgba(243, 240, 233, 0.45); opacity: 1; }
/* A date input paints its own calendar glyph in dark-on-light colours, which
   vanishes on ink. */
input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(1); opacity: 0.6; }

.field--error .input,
.field--error .select,
.field--error .textarea {
  border-bottom-color: var(--thread-on-dark);
  box-shadow: 0 1px 0 0 var(--thread-on-dark);
}
.field__error {
  display: none;
  position: relative;
  padding-left: var(--s5);
  font-size: var(--fs-small);
  color: var(--thread-on-dark);
}
.field__error::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 8px; height: 8px;
  border: 1px solid currentColor;
  transform: rotate(45deg);
}
.field--error .field__error { display: block; }

.honeypot { position: absolute; left: -9999px; opacity: 0; pointer-events: none; }

.form-status {
  display: none;
  padding: var(--s4) var(--s5);
  border: 1px solid var(--on-ink-line);
  font-size: var(--fs-small);
}
.form-status[data-state="ok"]      { display: block; background: var(--on-ink); color: var(--ink); border-color: var(--on-ink); }
.form-status[data-state="error"]   { display: block; border-color: var(--thread-on-dark); color: var(--thread-on-dark); }
.form-status[data-state="sending"] { display: block; color: var(--on-ink-2); }

.form-foot { font-size: var(--fs-small); color: var(--on-ink-2); }
.form-foot a { color: var(--on-ink); text-decoration: underline; text-underline-offset: 0.3em; }

.contact-list { display: grid; gap: var(--s5); margin: 0; }
.contact-list dt {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--on-ink-2);
  margin-bottom: var(--s2);
}
.contact-list dd { margin: 0; color: var(--on-ink); }
.contact-list a { text-decoration: underline; text-underline-offset: 0.3em; text-decoration-color: var(--on-ink-line); }
.contact-list a:hover { text-decoration-color: currentColor; }

.enquiry-grid { display: grid; gap: var(--s7); align-items: start; }
@media (min-width: 1000px) { .enquiry-grid { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: var(--s9); } }

/* 18. Footer ------------------------------------------------------------- */
.site-footer { border-top: var(--hair); padding-block: var(--s8) var(--s6); font-size: var(--fs-small); }
.footer-grid { display: grid; gap: var(--s6); }
@media (min-width: 760px) { .footer-grid { grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr)); } }
.footer-grid .mark { height: 28px; margin-bottom: var(--s4); }
.footer-col h2 {
  font-family: var(--annot);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s4);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.footer-col a { text-decoration: none; color: var(--ink-2); }
.footer-col a:hover { color: var(--thread); }
.footer-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s3) var(--s6);
  margin-top: var(--s8);
  padding-top: var(--s4);
  border-top: var(--hair);
  font-family: var(--annot);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* 19. Reduced motion & print --------------------------------------------- */
/* There is almost no motion to reduce — the page carries no scroll reveals,
   no hero animation and no staggered entrances, so it is complete the moment
   it paints. This covers the few state transitions that remain. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .site-header, .hero__actions, .actions, .site-footer { display: none !important; }
  body { background: #fff; color: #000; }
  .on-ink { background: #fff !important; color: #000 !important; }
  .tariff-panel { background: #fff; padding: 0; border-top-color: #000; }
  .tariff td { color: #000; }
  .marque { page-break-inside: avoid; }
  .faq__item { break-inside: avoid; }
  .faq__a { display: block !important; }
}
