/* OTS Portal — marketing site.
 *
 * One stylesheet, no framework, no external requests. The audience often
 * reads this behind a corporate proxy or on an air-gapped review machine, so
 * a page that needs the network to look right is a page that fails for them.
 * System fonts, inline SVG, everything local.
 */

:root {
  --bg:        #ffffff;
  --bg-alt:    #f6f7f9;
  --bg-card:   #ffffff;
  --fg:        #16181d;
  --fg-muted:  #5a6473;
  --line:      #dfe3e9;
  --accent:    #1b5fb4;
  --accent-fg: #ffffff;
  --accent-soft:#e8f0fb;
  --warn:      #9a4a12;
  --good:      #1f6b45;
  --code-bg:   #f2f4f7;
  --shadow:    0 1px 2px rgba(16, 24, 40, .06), 0 4px 12px rgba(16, 24, 40, .05);
  --radius:    10px;
  --measure:   38rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:        #14161a;
    --bg-alt:    #1a1d22;
    --bg-card:   #1c2026;
    --fg:        #e8eaee;
    --fg-muted:  #9aa4b2;
    --line:      #2c313a;
    --accent:    #6ea8f0;
    --accent-fg: #10141a;
    --accent-soft:#1a2637;
    --warn:      #e39a63;
    --good:      #6fc79b;
    --code-bg:   #1a1d22;
    --shadow:    0 1px 2px rgba(0, 0, 0, .4), 0 4px 14px rgba(0, 0, 0, .3);
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 17px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  font-synthesis-weight: none;
}

code, kbd, pre, .mono {
  font-family: ui-monospace, "Cascadia Mono", "Cascadia Code", Consolas,
               "Liberation Mono", monospace;
}

/* ── skip link and focus ────────────────────────────────────────────────── */

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--accent-fg);
  padding: .6rem 1rem; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; }

a { color: var(--accent); text-underline-offset: .18em; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ── layout ─────────────────────────────────────────────────────────────── */

.wrap { max-width: 68rem; margin: 0 auto; padding: 0 1.25rem; }
.narrow { max-width: var(--measure); }

section { padding: 3.5rem 0; }
section.alt { background: var(--bg-alt); border-block: 1px solid var(--line); }
@media (min-width: 48rem) { section { padding: 4.5rem 0; } }

/* ── header ─────────────────────────────────────────────────────────────── */

.site-header {
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  position: sticky; top: 0; z-index: 20;
}
.site-header .wrap {
  display: flex; align-items: center; gap: 1.25rem;
  min-height: 4rem; flex-wrap: wrap;
}
.brand {
  display: inline-flex; align-items: center; gap: .55rem;
  font-weight: 700; letter-spacing: -.01em; text-decoration: none;
  color: var(--fg); font-size: 1.05rem; white-space: nowrap;
}
.brand svg { flex: none; }
.brand .sub {
  font-weight: 400; color: var(--fg-muted); font-size: .82rem;
  display: none;
}
@media (min-width: 60rem) { .brand .sub { display: inline; } }

.site-nav { margin-left: auto; }
.site-nav ul {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: .35rem 1.15rem; margin: 0; padding: 0;
}
.site-nav a {
  color: var(--fg-muted); text-decoration: none; font-size: .93rem;
  padding: .35rem 0; display: inline-block; border-bottom: 2px solid transparent;
}
.site-nav a:hover { color: var(--fg); }
.site-nav a[aria-current="page"] {
  color: var(--fg); border-bottom-color: var(--accent); font-weight: 600;
}

/* ── hero ───────────────────────────────────────────────────────────────── */

.hero { padding: 3.5rem 0 3rem; }
@media (min-width: 48rem) { .hero { padding: 5rem 0 4rem; } }

.eyebrow {
  text-transform: uppercase; letter-spacing: .1em; font-size: .76rem;
  font-weight: 700; color: var(--accent); margin: 0 0 .9rem;
}
h1 {
  font-size: clamp(2rem, 1.3rem + 3vw, 3.1rem);
  line-height: 1.12; letter-spacing: -.025em; margin: 0 0 1rem;
  max-width: 20ch;
}
.lede {
  font-size: clamp(1.05rem, 1rem + .5vw, 1.25rem);
  color: var(--fg-muted); max-width: var(--measure); margin: 0 0 1.4rem;
}

h2 {
  font-size: clamp(1.4rem, 1.15rem + 1vw, 1.9rem);
  line-height: 1.2; letter-spacing: -.02em; margin: 0 0 .9rem;
}
h3 { font-size: 1.08rem; line-height: 1.3; margin: 0 0 .45rem; }
p { max-width: var(--measure); }
.section-lede { color: var(--fg-muted); max-width: var(--measure); margin: 0 0 2rem; }

/* ── buttons ────────────────────────────────────────────────────────────── */

.actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.6rem; }
.btn {
  display: inline-block; padding: .65rem 1.3rem; border-radius: 7px;
  font-weight: 600; font-size: .95rem; text-decoration: none;
  border: 1px solid var(--accent); background: var(--accent);
  color: var(--accent-fg);
}
.btn:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; color: var(--accent); }
.btn.ghost:hover { background: var(--accent-soft); filter: none; }

/* ── cards ──────────────────────────────────────────────────────────────── */

.grid { display: grid; gap: 1.1rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .grid.two   { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 52rem) { .grid.three { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 40rem) { .grid.four  { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62rem) { .grid.four  { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.35rem 1.4rem;
  box-shadow: var(--shadow);
}
.card p { margin: 0; color: var(--fg-muted); font-size: .95rem; max-width: none; }
.card p + p { margin-top: .7rem; }
a.card { display: block; text-decoration: none; color: inherit; }
a.card:hover { border-color: var(--accent); }
a.card .more {
  display: inline-block; margin-top: .9rem; color: var(--accent);
  font-weight: 600; font-size: .92rem;
}
.card .tag {
  display: inline-block; font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em;
  color: var(--fg-muted); margin-bottom: .5rem;
}

/* ── feature list ───────────────────────────────────────────────────────── */

.features { display: grid; gap: 1.8rem 2.5rem; grid-template-columns: 1fr; }
@media (min-width: 46rem) { .features { grid-template-columns: repeat(2, 1fr); } }
.feature h3 { display: flex; align-items: baseline; gap: .55rem; }
.feature p { color: var(--fg-muted); font-size: .95rem; margin: 0; max-width: none; }

/* ── callout ────────────────────────────────────────────────────────────── */

.callout {
  border-left: 3px solid var(--accent); background: var(--accent-soft);
  padding: 1rem 1.2rem; border-radius: 0 var(--radius) var(--radius) 0;
  margin: 1.8rem 0; max-width: var(--measure);
}
.callout p { margin: 0; }
.callout p + p { margin-top: .6rem; }
.callout strong { color: var(--fg); }

/* ── terminal / code ────────────────────────────────────────────────────── */

pre.term, pre.code {
  background: var(--code-bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.15rem;
  overflow-x: auto; font-size: .875rem; line-height: 1.55; margin: 1.2rem 0;
}
pre .prompt, pre .comment { color: var(--fg-muted); }
pre .flag { color: var(--accent); }
pre .bad  { color: var(--warn); font-weight: 600; }
pre .ok   { color: var(--good); font-weight: 600; }
code:not(pre code) {
  background: var(--code-bg); padding: .12em .38em; border-radius: 4px;
  font-size: .89em; border: 1px solid var(--line);
}

/* ── tables ─────────────────────────────────────────────────────────────── */

.table-scroll { overflow-x: auto; margin: 1.4rem 0; }
table { border-collapse: collapse; width: 100%; font-size: .93rem; }
th, td {
  text-align: left; padding: .6rem .8rem;
  border-bottom: 1px solid var(--line); vertical-align: top;
}
th {
  font-size: .76rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--fg-muted); font-weight: 700;
}

/* ── steps ──────────────────────────────────────────────────────────────── */

ol.steps { counter-reset: step; list-style: none; padding: 0; margin: 1.5rem 0; }
ol.steps li {
  counter-increment: step; position: relative;
  padding-left: 3rem; margin-bottom: 1.4rem; max-width: var(--measure);
}
ol.steps li::before {
  content: counter(step); position: absolute; left: 0; top: -.1rem;
  width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center; font-weight: 700; font-size: .95rem;
}
ol.steps h3 { margin-bottom: .3rem; }
ol.steps p { color: var(--fg-muted); margin: 0; font-size: .95rem; }

/* ── plain lists ────────────────────────────────────────────────────────── */

ul.ticks { list-style: none; padding: 0; margin: 1.2rem 0; }
ul.ticks li {
  position: relative; padding-left: 1.75rem; margin-bottom: .7rem;
  max-width: var(--measure); color: var(--fg-muted);
}
ul.ticks li::before {
  content: ""; position: absolute; left: .15rem; top: .55em;
  width: .55rem; height: .55rem; border-radius: 2px; background: var(--accent);
}
ul.ticks strong { color: var(--fg); font-weight: 600; }

/* ── demo frame ─────────────────────────────────────────────────────────── */

.demo-frame {
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--bg-card); margin: 1.5rem 0;
  box-shadow: var(--shadow);
}
.demo-frame iframe { display: block; width: 100%; height: 34rem; border: 0; }
.demo-frame .bar {
  padding: .55rem .9rem; border-bottom: 1px solid var(--line);
  background: var(--bg-alt); font-size: .82rem; color: var(--fg-muted);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.demo-frame .bar a { font-weight: 600; }

/* ── footer ─────────────────────────────────────────────────────────────── */

.site-footer {
  border-top: 1px solid var(--line); background: var(--bg-alt);
  padding: 2.5rem 0; margin-top: 1rem; font-size: .92rem;
}
.site-footer .cols {
  display: grid; gap: 1.8rem; grid-template-columns: 1fr;
}
@media (min-width: 44rem) {
  .site-footer .cols { grid-template-columns: 1.4fr 1fr 1fr; }
}
.site-footer h2 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--fg-muted); margin: 0 0 .7rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .45rem; }
.site-footer a { color: var(--fg-muted); text-decoration: none; }
.site-footer a:hover { color: var(--accent); text-decoration: underline; }
.site-footer .legal {
  margin-top: 2rem; padding-top: 1.3rem; border-top: 1px solid var(--line);
  color: var(--fg-muted); font-size: .86rem;
}
.site-footer .legal p { max-width: none; margin: 0 0 .4rem; }

/* ── print ──────────────────────────────────────────────────────────────── */

@media print {
  .site-header, .site-nav, .actions, .demo-frame iframe { display: none; }
  body { font-size: 11pt; }
  section { padding: 1rem 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ── sub-navigation ─────────────────────────────────────────────────────── */
/* A second row rather than a dropdown: hover menus are hostile on touch and
   need JavaScript to be accessible, and this site has neither. */

.sub-nav {
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
}
.sub-nav ul {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: .1rem 1.1rem; margin: 0; padding: .55rem 0;
}
.sub-nav a {
  color: var(--fg-muted); text-decoration: none; font-size: .88rem;
  padding: .2rem 0; display: inline-block; border-bottom: 2px solid transparent;
}
.sub-nav a:hover { color: var(--fg); }
.sub-nav a[aria-current="page"] {
  color: var(--accent); border-bottom-color: var(--accent); font-weight: 600;
}

/* ── screenshots ────────────────────────────────────────────────────────── */

figure.shot { margin: 1.8rem 0; }
figure.shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); background: var(--bg-card);
}
figure.shot figcaption {
  margin-top: .7rem; color: var(--fg-muted); font-size: .9rem;
  max-width: var(--measure);
}
figure.shot figcaption strong { color: var(--fg); font-weight: 600; }

/* A screenshot beside its explanation, stacking on narrow screens. */
.shot-row { display: grid; gap: 1.6rem; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 54rem) { .shot-row { grid-template-columns: 3fr 2fr; } }
.shot-row figure.shot { margin: 0; }
.shot-row .prose p { max-width: none; }
.shot-row .prose h3 { margin-top: 0; }

.footer-blurb { color: var(--fg-muted); margin: 0 0 .8rem; max-width: 24rem; }

/* ── hero carousel ──────────────────────────────────────────────────────── */
/* Progressive enhancement: without JavaScript the slides simply stack and all
   four are readable. `.is-enhanced` is added by the script, and only then are
   they collapsed into one place. A carousel that is blank without JS is worse
   than no carousel. */

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.hero-carousel { padding: 3rem 0 2.5rem; }
@media (min-width: 48rem) { .hero-carousel { padding: 4.5rem 0 3rem; } }

.hero-carousel .slide + .slide { margin-top: 2.5rem; }
.hero-carousel h2 {
  font-size: clamp(2rem, 1.3rem + 3vw, 3.1rem);
  line-height: 1.12; letter-spacing: -.025em; margin: 0 0 1rem;
  max-width: 20ch;
}
.hero-carousel .lede { margin-bottom: .9rem; }
.slide-link { margin: 0; }
.slide-link a { font-weight: 600; text-decoration: none; }
.slide-link a:hover { text-decoration: underline; }

/* Once the script is running, the slides share one box and fade between. */
.hero-carousel.is-enhanced .slides {
  display: grid;
  /* One cell, every slide in it: the tallest slide sets the height, so
     nothing below the carousel jumps as the text changes. */
  grid-template-areas: "slide";
  align-items: start;
}
.hero-carousel.is-enhanced .slide {
  grid-area: slide; margin: 0 !important;
  opacity: 0; visibility: hidden;
  transform: translateY(.5rem);
  transition: opacity .45s ease, transform .45s ease, visibility 0s .45s;
}
.hero-carousel.is-enhanced .slide.is-active {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .45s ease, transform .45s ease;
}

.carousel-controls {
  display: flex; align-items: center; gap: 1.2rem;
  margin-top: 1.8rem; flex-wrap: wrap;
}
.hero-carousel:not(.is-enhanced) .carousel-controls { display: none; }

.dots { display: flex; gap: .2rem; }
/* The visible mark is a thin bar, but the button itself is a comfortable
   target: a 6px-high control is unusable on a phone, which is where a hero
   carousel is most likely to be operated by hand. */
.dots button {
  width: 3rem; height: 2.5rem; padding: 0; border: 0; cursor: pointer;
  background: none; display: grid; place-items: center;
}
.dots button::before {
  content: ""; display: block; width: 2.4rem; height: .4rem;
  border-radius: 2px; background: var(--line); transition: background .2s;
}
.dots button:hover::before { background: var(--fg-muted); }
.dots button[aria-selected="true"]::before { background: var(--accent); }

button.pause {
  border: 1px solid var(--line); background: transparent; cursor: pointer;
  color: var(--fg-muted); font: inherit; font-size: .82rem;
  padding: .25rem .8rem; border-radius: 999px;
}
button.pause:hover { color: var(--fg); border-color: var(--fg-muted); }

@media (prefers-reduced-motion: reduce) {
  .hero-carousel.is-enhanced .slide { transition: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   PHONES
   Everything below 48rem. Measured on a 375x667 screen, which is where the
   problems showed: the header was taking 31% of the viewport permanently,
   commands were 40% off-screen, and the nav targets were 32px.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 47.99rem) {

  /* ── 1. Give the screen back ──────────────────────────────────────────
     The sub-nav wrapped to three lines and the whole header was sticky:
     205px of permanent chrome. Now it is one scrollable row, and the header
     scrolls away like everything else. A phone screen is too short to spend
     a third of it on navigation that is not being used. */

  .site-header { position: static; }

  .sub-nav ul {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Bleed to the screen edges so the row reads as scrollable rather than
       as a list that happens to be clipped. */
    margin-inline: -1.25rem;
    padding-inline: 1.25rem;
  }
  .sub-nav ul::-webkit-scrollbar { display: none; }
  .sub-nav li { flex: 0 0 auto; scroll-snap-align: start; }

  /* ── 5. Tap targets ───────────────────────────────────────────────────
     32px was below what a thumb can reliably hit. */

  .site-nav a { padding: .8rem 0; }
  .sub-nav a  { padding: .7rem 0; }
  .brand      { padding: .5rem 0; }
  .site-footer a { display: inline-block; padding: .3rem 0; }

  /* ── 4. Nothing hidden off the right edge ─────────────────────────────
     Commands were cut off at 40% of their length, recoverable only by a
     horizontal scroll most people never try. Wrapping with a hanging indent
     keeps the continuation visibly part of the same line. */

  pre.code, pre.term {
    white-space: pre-wrap;
    overflow-wrap: break-word;
    text-indent: -1.4em;
    padding-left: calc(1.15rem + 1.4em);
  }

  /* ── 6. Small text, less small ────────────────────────────────────────
     The floor was 12.16px. */

  .eyebrow, .card .tag { font-size: .84rem; }
  .card p, .feature p, figure.shot figcaption,
  .site-footer, .sub-nav a { font-size: .95rem; }

  /* Headlines wrap rather than run off, and the hero is less towering. */
  h1, .hero-carousel h2 { max-width: none; }
  .hero-carousel { padding: 2.25rem 0 2rem; }
  section { padding: 2.75rem 0; }

  /* ── 2. Screenshots ───────────────────────────────────────────────────
     A 1370px capture at 335px is 24% scale — unreadable. Where a narrow
     crop exists it is served instead; either way the figure is tappable and
     opens the full image, which is the only way to read the detail. */

  figure.shot img { border-radius: 6px; }
  figure.shot a.zoom::after {
    content: "Tap to open full size";
    display: block; margin-top: .5rem;
    font-size: .84rem; color: var(--accent); font-weight: 600;
  }

  /* ── 3. Demos open as their own page ──────────────────────────────────
     An iframe 544px tall holding 1600px of content is a scroll-within-a-
     scroll: a swipe moves the wrong thing. On a phone the demo gets the
     whole screen instead. */

  .demo-frame iframe { display: none; }
  .demo-open {
    display: block; margin: 0; padding: 1rem 1.15rem;
    text-align: center; text-decoration: none; font-weight: 600;
    color: var(--accent); background: var(--bg-card);
  }
  .demo-open:hover { background: var(--accent-soft); }
  .demo-open .hint {
    display: block; font-weight: 400; font-size: .86rem;
    color: var(--fg-muted); margin-top: .2rem;
  }
}

/* On anything wider the demo is embedded and the button is redundant. */
@media (min-width: 48rem) { .demo-open { display: none; } }

/* ── a shorter header on phones ─────────────────────────────────────────
   The brand and the tabs were wrapping to two rows, and with the enlarged
   tap targets that came to 185px before any content. Getting them onto one
   row roughly halves it. Targets stay at 44px — the point was never to make
   them small again. */

@media (max-width: 47.99rem) {
  .site-header .wrap {
    min-height: 0;
    padding-block: .15rem;
    gap: .75rem;
    flex-wrap: nowrap;          /* brand and tabs share one line */
  }
  .brand { padding: .35rem 0; font-size: 1rem; }
  .brand svg { width: 22px; height: 22px; }

  .site-nav ul { gap: .1rem .7rem; flex-wrap: nowrap; }
  .site-nav a { padding: .62rem 0; font-size: .86rem; white-space: nowrap; }

  .sub-nav ul { padding: .35rem 0; }
  .sub-nav a  { padding: .6rem 0; }
}

/* On phones the wordmark gives way to the mark alone.
   Measured: three tabs left 24px spare at 375px, and the Contact tab needs
   about 63px more than that. Something had to go, and the mark still says
   whose site this is while the tabs say what is on it. Hidden from sight
   only — the link keeps its accessible name, or the one route back to the
   landing page would be an unlabelled icon. The wordmark returns at tablet
   width, where there is room for both. */
@media (max-width: 47.99rem) {
  .brand .word {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
}

/* ── enquiry form ───────────────────────────────────────────────────────────
   The one place on the site a visitor types rather than reads, so the rules
   are different: every control is at least 44px tall, and every font is at
   least 16px — below that iOS Safari zooms the viewport on focus and never
   zooms back out, which strands the visitor mid-form. */

.enquiry { margin-top: .5rem; }

.field { margin-bottom: 1.4rem; }

/* Two fields share a row once there is room; below that they stack, because
   a half-width field on a phone is a field nobody can read their own typing
   in. */
.field-row { display: grid; gap: 0 1rem; grid-template-columns: 1fr; }
@media (min-width: 34rem) {
  .field-row { grid-template-columns: 1fr 1fr; }
}

/* Field labels sit above their control. Choice labels wrap theirs and lay it
   out sideways, so they are excluded here rather than fighting this rule from
   below — a bare .choice loses to .enquiry label on specificity, which is how
   the tick ended up on its own line once already. */
.enquiry label:not(.choice),
.enquiry legend {
  display: block; font-weight: 600; font-size: .95rem;
  margin: 0 0 .4rem; color: var(--fg); padding: 0;
}

.req { color: var(--accent); font-weight: 700; }

.enquiry input[type="text"],
.enquiry input[type="email"],
.enquiry input[type="tel"],
.enquiry textarea {
  width: 100%; min-height: 2.9rem;
  padding: .6rem .75rem;
  font: inherit; font-size: 16px;          /* see the note above — not 15px */
  color: var(--fg); background: var(--bg-card);
  border: 1px solid var(--line); border-radius: 7px;
}
.enquiry textarea { min-height: 9rem; resize: vertical; line-height: 1.55; }

.enquiry input:hover,
.enquiry textarea:hover { border-color: var(--fg-muted); }

/* :focus-visible governs keyboard focus site-wide, but a form field earns a
   ring however it was reached — a tap that lands in the wrong box should be
   obvious immediately. */
.enquiry input:focus,
.enquiry textarea:focus {
  outline: 3px solid var(--accent); outline-offset: 1px;
  border-color: var(--accent);
}

.enquiry input:invalid:not(:placeholder-shown) { border-color: var(--warn); }

.hint {
  font-size: .85rem; color: var(--fg-muted); margin: .4rem 0 0;
  max-width: none;
}
.hint.warn { color: var(--warn); }

/* ── grouped choices ─────────────────────────────────────────────────────── */

.enquiry fieldset { border: 0; margin: 0 0 1.4rem; padding: 0; }

.choices { display: grid; gap: .1rem; grid-template-columns: 1fr; }
@media (min-width: 34rem) {
  .choices { grid-template-columns: repeat(2, 1fr); gap: .1rem 1rem; }
}

/* The whole row is the target, not just the 16px box inside it. */
.choice {
  display: flex; align-items: flex-start; gap: .6rem;
  min-height: 44px; padding: .5rem 0; margin: 0;
  font-weight: 400; font-size: .97rem; cursor: pointer;
}
.choice input { flex: none; width: 1.15rem; height: 1.15rem; margin-top: .2rem; }
.choice span { display: block; }
.choice:hover { color: var(--accent); }

.choice.consent {
  align-items: flex-start; background: var(--bg-alt);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .9rem 1rem;
}
.choice.consent .hint { display: block; margin-top: .3rem; }

/* ── the honeypot ────────────────────────────────────────────────────────────
   Off-screen rather than display:none or hidden. A bot worth defending
   against checks for those two and skips the field; this one it fills in,
   and the endpoint drops anything that arrives with it set. */
.hp {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

/* ── result banner ───────────────────────────────────────────────────────── */

.form-status {
  padding: .9rem 1.1rem; border-radius: var(--radius);
  margin: 0 0 1.5rem; font-weight: 600; border: 1px solid var(--line);
}
.form-status.ok  { color: var(--good); border-color: var(--good);
                   background: var(--bg-alt); }
.form-status.bad { color: var(--warn); border-color: var(--warn);
                   background: var(--bg-alt); }

.enquiry button[disabled] { opacity: .6; cursor: default; filter: none; }

.form-foot { margin-top: 1.2rem; }

/* The submit button is the one control a mis-tap costs something, so it gets
   the full target height on touch even though .btn is smaller elsewhere. */
@media (max-width: 47.99rem) {
  .enquiry button[type="submit"] { min-height: 48px; width: 100%; }
  .enquiry .actions { margin-top: 1.4rem; }
}

/* Four tabs fit a 375px phone with room, but only just at 320px — measured at
   3px, which is inside the margin any font substitution could eat. Closing the
   gaps buys it back without shrinking the type, since the tabs are already at
   the smallest size worth reading. */
@media (max-width: 22.5rem) {
  .site-header .wrap { gap: .5rem; }
  .site-nav ul { gap: .1rem .45rem; }
}
