/* ==========================================================================
   Specified Inspections — site stylesheet
   --------------------------------------------------------------------------
   One stylesheet for the whole site. Every page links to this file.

   How this file is organised (search for these headings):
     1. Tokens        — the colours, fonts and spacing used everywhere
     2. Base          — defaults for plain text, links, headings
     3. Layout        — the container, sections, grids
     4. Nav & footer  — the bars at the top and bottom of every page
     5. Components    — buttons, cards, tables, badges, forms
     6. Page blocks   — hero, feature rows, pricing, FAQ, report viewer
     7. Responsive    — what changes on a phone

   Colours come from the app itself (styles.css in the Field Inspection App
   folder) so the website and the product look related.
   ========================================================================== */

/* ============ 1. TOKENS ================================================== */

:root {
  /* Brand — taken from the app's own palette */
  --navy:        #1a2b4a;
  --navy-deep:   #0f1c30;
  --navy-soft:   #243558;
  --blue:        #2c6fad;
  --blue-dark:   #21578a;
  --blue-wash:   #e8f2fc;
  --amber:       #d4800a;
  --amber-wash:  #fff4e0;
  --green:       #1a7a3c;
  --green-wash:  #eaf7ee;
  --red:         #c0392b;

  /* Neutrals */
  --ink:         #1e2430;
  --ink-soft:    #4d5665;
  --ink-faint:   #6f7888;
  --line:        #e3e8ef;
  --line-soft:   #eef2f7;
  --paper:       #ffffff;
  --paper-tint:  #f6f8fb;
  --paper-deep:  #eef2f7;

  /* Type */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Spacing scale — use these instead of typing random pixel values */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;

  --radius:     10px;
  --radius-sm:  6px;
  --radius-lg:  16px;
  --shadow:     0 1px 3px rgba(15, 28, 48, .08), 0 8px 24px rgba(15, 28, 48, .06);
  --shadow-lg:  0 2px 6px rgba(15, 28, 48, .10), 0 24px 56px rgba(15, 28, 48, .12);
  --container:  1140px;
}

/* ============ 2. BASE ==================================================== */

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

html { scroll-behavior: smooth; scroll-padding-top: 90px; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  color: var(--navy-deep);
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 var(--s4);
  font-weight: 700;
}
h1 { font-size: clamp(2.1rem, 4.6vw, 3.4rem); letter-spacing: -0.03em; }
h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); }
h3 { font-size: 1.22rem; }
h4 { font-size: 1.02rem; }

p { margin: 0 0 var(--s4); }
p:last-child { margin-bottom: 0; }

a { color: var(--blue-dark); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--navy); }

img, svg { max-width: 100%; height: auto; }

ul, ol { margin: 0 0 var(--s4); padding-left: 1.25em; }
li { margin-bottom: var(--s2); }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s7) 0; }

code { font-family: var(--mono); font-size: .9em; background: var(--paper-deep);
       padding: 2px 6px; border-radius: 4px; }

::selection { background: var(--blue-wash); }

/* Accessibility: a keyboard user must always be able to see where they are. */
:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--navy); color: #fff; padding: var(--s3) var(--s5);
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* ============ 3. LAYOUT ================================================= */

.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--s5); }
.container-narrow { max-width: 780px; }

section { padding: var(--s9) 0; }
section.tight { padding: var(--s8) 0; }

.tint      { background: var(--paper-tint); }
.tint-deep { background: var(--paper-deep); }
.dark      { background: var(--navy-deep); color: #cfd8e6; }
.dark h1, .dark h2, .dark h3, .dark h4 { color: #fff; }
.dark a { color: #9ec8f0; }

/* A section's opening block: small label, big heading, one paragraph. */
.section-head { max-width: 720px; margin-bottom: var(--s7); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head p { color: var(--ink-soft); font-size: 1.09rem; margin-bottom: 0; }

.eyebrow {
  font-size: .78rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--blue);
  margin: 0 0 var(--s3);
}
.dark .eyebrow { color: #7fb3e0; }

.lede { font-size: 1.16rem; color: var(--ink-soft); }

.grid { display: grid; gap: var(--s5); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.split {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--s8); align-items: center;
}
.split.wide-left  { grid-template-columns: 1.15fr .85fr; }
.split.wide-right { grid-template-columns: .85fr 1.15fr; }

/* ============ 4. NAV & FOOTER =========================================== */

.nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  display: flex; align-items: center; gap: var(--s5);
  height: 68px;
}
/* The wordmark sits on two lines — "Specified" over "Inspection Platforms" —
   with the mark deliberately taller than that block so it leads the pair
   rather than merely matching it. 48px against a 34px text block, inside a
   68px bar. If you push it much past 52px, raise .nav-inner's height first.

   Don't be tempted by align-items:stretch to size it automatically — an <img>
   with width:auto takes its width from its height, so stretching it makes the
   sizing circular and the mark balloons to fill the row. */
.brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; letter-spacing: -0.02em;
  color: var(--navy-deep); text-decoration: none; white-space: nowrap;
}
.brand:hover { color: var(--navy-deep); }
.brand-mark { width: 48px; height: 48px; flex: 0 0 48px; }
.brand-text { display: flex; flex-direction: column; justify-content: center; }
.brand-name { font-size: 1.12rem; line-height: 1.15; }
.brand-sub {
  color: var(--ink-faint); font-weight: 500;
  font-size: .74rem; line-height: 1.15; letter-spacing: 0;
}

/* Footer copy of the same wordmark, on navy. */
.footer-brand .brand { color: #fff; margin-bottom: var(--s4); }
.footer-brand .brand:hover { color: #fff; }
.footer-brand .brand-sub { color: #8fa0b8; }

.nav-links { display: flex; align-items: center; gap: var(--s2); margin-left: auto; }
.nav-links a {
  color: var(--ink-soft); text-decoration: none; font-size: .95rem; font-weight: 500;
  padding: 8px 12px; border-radius: var(--radius-sm);
}
.nav-links a:hover { color: var(--navy-deep); background: var(--paper-tint); }
.nav-links a.current { color: var(--navy-deep); font-weight: 600; }
.nav-links .btn { color: #fff; }
.nav-links .btn:hover { color: #fff; }

.nav-toggle {
  display: none; margin-left: auto;
  background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 8px 10px; cursor: pointer; color: var(--navy-deep);
}

.footer { background: var(--navy-deep); color: #97a5ba; padding: var(--s8) 0 var(--s6); }
.footer h4 { color: #fff; font-size: .82rem; letter-spacing: .1em;
             text-transform: uppercase; margin-bottom: var(--s4); }
.footer a { color: #b9c6d8; text-decoration: none; display: block; margin-bottom: 10px; font-size: .95rem; }
.footer a:hover { color: #fff; text-decoration: underline; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: var(--s6); }
.footer-brand p { font-size: .93rem; max-width: 34ch; }
.footer-bottom {
  margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid rgba(255,255,255,.10);
  display: flex; flex-wrap: wrap; gap: var(--s4); justify-content: space-between;
  font-size: .86rem; color: #7d8ca3;
}

/* ============ 5. COMPONENTS ============================================= */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 24px; border-radius: var(--radius-sm);
  background: var(--blue); color: #fff; border: 1px solid var(--blue);
  font: inherit; font-size: .97rem; font-weight: 600; text-decoration: none;
  cursor: pointer; transition: background .15s, border-color .15s, transform .05s;
  white-space: nowrap;
}
.btn:hover { background: var(--blue-dark); border-color: var(--blue-dark); color: #fff; }
.btn:active { transform: translateY(1px); }

.btn-ghost { background: transparent; color: var(--navy-deep); border-color: var(--line); }
.btn-ghost:hover { background: var(--paper-tint); color: var(--navy-deep); border-color: #cbd5e1; }
.dark .btn-ghost { color: #fff; border-color: rgba(255,255,255,.28); }
.dark .btn-ghost:hover { background: rgba(255,255,255,.08); color: #fff; }

.btn-navy { background: var(--navy); border-color: var(--navy); }
.btn-navy:hover { background: var(--navy-deep); border-color: var(--navy-deep); }

.btn-sm { padding: 9px 16px; font-size: .9rem; }
.btn-lg { padding: 16px 30px; font-size: 1.03rem; }
.btn-block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); }
.btn-row.center { justify-content: center; }

.card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s5);
}
.card h3 { margin-bottom: var(--s2); }
.card p:last-child { margin-bottom: 0; color: var(--ink-soft); font-size: .97rem; }
.card-lift { box-shadow: var(--shadow); border-color: transparent; }

.icon-badge {
  width: 42px; height: 42px; border-radius: var(--radius-sm);
  background: var(--blue-wash); color: var(--blue-dark);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: var(--s4);
}
.icon-badge svg { width: 22px; height: 22px; }
.icon-badge.amber { background: var(--amber-wash); color: var(--amber); }
.icon-badge.green { background: var(--green-wash); color: var(--green); }

.badge {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: .76rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--blue-wash); color: var(--blue-dark);
}
.badge-amber { background: var(--amber-wash); color: #9c5c00; }
.badge-green { background: var(--green-wash); color: var(--green); }
.badge-grey  { background: var(--paper-deep); color: var(--ink-faint); }

/* A short list with ticks, used for feature bullets */
.ticks { list-style: none; padding: 0; margin: 0; }
.ticks li {
  position: relative; padding-left: 30px; margin-bottom: var(--s3);
  color: var(--ink-soft);
}
.ticks li::before {
  content: ""; position: absolute; left: 0; top: .46em;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a7a3c' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/11px no-repeat;
}
.ticks strong { color: var(--ink); font-weight: 600; }

/* Market switcher — one platform per tab, on the home page.
   The panels are plain cards; only the tab strip is new furniture. Hiding is
   done with the hidden attribute so a panel is gone from the accessibility
   tree too, not just off-screen. */
.markets { margin-top: var(--s5); }
.market-tabs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2);
  margin-bottom: var(--s5);
}
.market-tab {
  font: inherit; font-size: .92rem; font-weight: 600; cursor: pointer;
  padding: 9px var(--s4); border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink-soft);
}
.market-tab:hover { color: var(--navy-deep); background: var(--paper-tint); }
.market-tab.is-active {
  background: var(--navy-deep); border-color: var(--navy-deep); color: #fff;
}
.market-panel .card { max-width: 760px; margin: 0 auto; }
.market-panel h4 {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin: 0 0 var(--s3); font-size: 1.15rem;
}
.market-panel .ticks { margin-top: var(--s4); }
.market-note {
  margin: var(--s4) 0 0; padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: .92rem; color: var(--ink-soft);
}
.market-note strong { color: var(--ink); }

/* A card heading that carries a status badge beside it. */
.card h3 .badge { margin-left: var(--s2); vertical-align: middle; }

table.compare {
  width: 100%; border-collapse: collapse; font-size: .95rem;
  background: var(--paper);
}
table.compare th, table.compare td {
  padding: 14px var(--s4); text-align: left; border-bottom: 1px solid var(--line);
  vertical-align: top;
}
table.compare thead th {
  font-size: .8rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-faint); border-bottom: 2px solid var(--line);
  background: var(--paper-tint); white-space: nowrap;
}
table.compare tbody th { font-weight: 600; color: var(--navy-deep); }
table.compare td { color: var(--ink-soft); }
table.compare .yes { color: var(--green); font-weight: 700; }
table.compare .no  { color: var(--ink-faint); }
/* A tolerance failure has to read as a failure, not as a quiet grey no. */
table.compare .fail { color: var(--red); font-weight: 700; }
/* The spec table has a wider first column: the row labels are sentences. */
table.compare.spec tbody th { width: 11.5rem; line-height: 1.35; }
table.compare.spec tbody th .hint { display: block; font-weight: 400; font-size: .82rem; color: var(--ink-faint); }
table.compare.spec { min-width: 44rem; }
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }

/* Forms */
.field { margin-bottom: var(--s4); }
.field label {
  display: block; font-size: .88rem; font-weight: 600;
  color: var(--navy-deep); margin-bottom: 6px;
}
.field .hint { font-weight: 400; color: var(--ink-faint); }
.field input, .field select, .field textarea {
  width: 100%; padding: 12px var(--s3); font: inherit; font-size: .97rem;
  color: var(--ink); background: var(--paper);
  border: 1px solid #cbd5e1; border-radius: var(--radius-sm);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--blue); outline: 3px solid var(--blue-wash); outline-offset: 0;
}
.field textarea { min-height: 110px; resize: vertical; }

.form-note { font-size: .85rem; color: var(--ink-faint); }

.note {
  border-left: 3px solid var(--blue); background: var(--blue-wash);
  padding: var(--s4) var(--s5); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: .95rem;
}
.note.amber { border-color: var(--amber); background: var(--amber-wash); }
.note strong { color: var(--navy-deep); }

/* ============ 6. PAGE BLOCKS ============================================ */

/* --- Hero --- */
.hero {
  background:
    radial-gradient(1100px 460px at 78% -8%, rgba(44, 111, 173, .13), transparent 62%),
    linear-gradient(180deg, var(--paper-tint), var(--paper));
  border-bottom: 1px solid var(--line);
  padding: var(--s9) 0 var(--s8);
}
.hero h1 { max-width: 15ch; }
.hero .subhead { font-size: 1.19rem; color: var(--ink-soft); max-width: 52ch; margin-bottom: var(--s6); }
.hero-note { font-size: .88rem; color: var(--ink-faint); margin-top: var(--s4); }
.hero-inner.center { text-align: center; margin: 0 auto; max-width: 780px; }
.hero-inner.center h1, .hero-inner.center .subhead { margin-left: auto; margin-right: auto; }

/* Page-top band for interior pages (smaller than the home hero) */
.page-head {
  background: linear-gradient(180deg, var(--paper-tint), var(--paper));
  border-bottom: 1px solid var(--line);
  padding: var(--s8) 0 var(--s7);
}
.page-head p { color: var(--ink-soft); font-size: 1.1rem; max-width: 62ch; margin-bottom: 0; }

/* --- The iPad mock used in the hero and feature rows --- */
.device {
  position: relative; background: var(--navy-deep);
  border-radius: 22px; padding: 12px; box-shadow: var(--shadow-lg);
}
.device-screen {
  background: var(--paper); border-radius: 12px; overflow: hidden;
  aspect-ratio: 4 / 3; display: flex; flex-direction: column;
}
.device-bar {
  background: var(--navy); color: #fff; padding: 9px var(--s3);
  font-size: .74rem; display: flex; align-items: center; gap: 8px;
  letter-spacing: .01em;
}
.device-bar .dot { width: 7px; height: 7px; border-radius: 50%; background: #4ade80; }
.device-body {
  padding: var(--s3); overflow: hidden; font-size: .74rem;
  /* min-height:0 matters: without it this flex child refuses to shrink below
     its content, and a long mock stretches the screen out of its 4:3 shape. */
  flex: 1; min-height: 0;
}

.mock-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  margin-bottom: 7px; background: var(--paper);
}
.mock-row .label { flex: 1; color: var(--ink); }
.mock-pill {
  font-size: .66rem; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .04em;
}
/* These match the app's own status colours: Yes green, No purple,
   Pending orange, In-Progress blue, AI (action item) dark red, N/A grey. */
.mock-pill.yes  { background: var(--green-wash); color: var(--green); }
.mock-pill.no   { background: #f4ecfa; color: #8e44ad; }
.mock-pill.pend { background: var(--amber-wash); color: #9c5c00; }
.mock-pill.prog { background: var(--blue-wash); color: var(--blue-dark); }
.mock-pill.ai   { background: #fbeaea; color: #8e1f1f; }
.mock-pill.na   { background: var(--paper-deep); color: var(--ink-faint); }
.mock-thumb { width: 26px; height: 20px; border-radius: 3px; background: var(--paper-deep); flex: 0 0 26px; }

/* --- Stat strip --- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s5); }
.stat { text-align: center; }
.stat .num {
  font-size: 2.5rem; font-weight: 700; color: var(--navy-deep);
  letter-spacing: -0.03em; line-height: 1.1;
}
.dark .stat .num { color: #fff; }
.stat .cap { font-size: .9rem; color: var(--ink-faint); margin-top: 4px; }
.dark .stat .cap { color: #97a5ba; }

/* --- Logo / credibility strip --- */
.strip { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
         background: var(--paper-tint); padding: var(--s5) 0; }
.strip-inner { display: flex; flex-wrap: wrap; align-items: center;
               justify-content: center; gap: var(--s3) var(--s6); }
.strip-item { font-size: .88rem; color: var(--ink-faint); font-weight: 600;
              letter-spacing: .02em; }

/* --- Steps --- */
.steps { counter-reset: step; display: grid; gap: var(--s5); }
.step { position: relative; padding-left: 62px; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--navy); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1rem;
}
.step h3 { margin-bottom: 6px; }
.step p { color: var(--ink-soft); margin-bottom: 0; font-size: .98rem; }

/* How it works as a row: numbered steps joined by a line, each with an icon,
   a one-line heading and a few short bullets instead of a paragraph. The
   numbers still come from the .steps counter above. The ring around each
   number is the section's own tint, so the joining line stops short of it. */
.steps-row { grid-template-columns: repeat(4, 1fr); position: relative; }
.steps-row::before {
  content: ""; position: absolute; top: 20px; left: 20px; right: 20px;
  height: 2px; background: var(--line);
}
.steps-row .step { padding-left: 0; padding-top: 58px; }
.steps-row .step::before { z-index: 1; box-shadow: 0 0 0 6px var(--paper-tint); }
.steps-row .icon-badge {
  position: absolute; top: 0; left: 52px; z-index: 1;
  width: 40px; height: 40px; margin: 0;
  box-shadow: 0 0 0 6px var(--paper-tint);
}
.steps-row .step h3 { font-size: 1.08rem; margin-bottom: var(--s3); }
.steps-row .ticks li { font-size: .92rem; margin-bottom: 6px; }

@media (max-width: 900px) {
  .steps-row { grid-template-columns: repeat(2, 1fr); gap: var(--s6) var(--s5); }
  .steps-row::before { display: none; }
}
@media (max-width: 620px) {
  .steps-row { grid-template-columns: 1fr; }
}

/* --- Pricing --- */
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); align-items: start; }
.plan {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s6) var(--s5);
  display: flex; flex-direction: column; height: 100%;
}
.plan.featured {
  border: 2px solid var(--blue); box-shadow: var(--shadow);
  position: relative;
}
/* Any featured plan may name its own ribbon with data-flag; without one it
   keeps the default wording, which is what the seat tier wants. */
.plan.featured[data-flag]::after { content: attr(data-flag); }
.plan.featured::after {
  content: "Most firms start here"; position: absolute; top: -12px; left: 50%;
  transform: translateX(-50%); background: var(--blue); color: #fff;
  font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 12px; border-radius: 999px; white-space: nowrap;
}
.plan h3 { font-size: 1.1rem; margin-bottom: 4px; }
.plan .plan-for { color: var(--ink-faint); font-size: .9rem; margin-bottom: var(--s5); min-height: 2.6em; }
.plan .price { font-size: 2.6rem; font-weight: 700; color: var(--navy-deep); letter-spacing: -0.03em; line-height: 1; }
.plan .price small { font-size: .95rem; font-weight: 500; color: var(--ink-faint); letter-spacing: 0; }
.plan .price-note { font-size: .85rem; color: var(--ink-faint); margin: 6px 0 var(--s5); }
.plan .ticks { margin: var(--s5) 0; flex: 1; }
.plan .ticks li { font-size: .93rem; }

/* --- FAQ --- */
.faq details {
  border-bottom: 1px solid var(--line); padding: var(--s4) 0;
}
.faq summary {
  cursor: pointer; font-weight: 600; color: var(--navy-deep);
  font-size: 1.03rem; list-style: none; display: flex; gap: var(--s3);
  align-items: flex-start;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before {
  content: "+"; color: var(--blue); font-weight: 700; font-size: 1.3rem;
  line-height: 1.15; flex: 0 0 14px;
}
.faq details[open] summary::before { content: "\2013"; }
.faq details p { margin: var(--s3) 0 0 26px; color: var(--ink-soft); font-size: .98rem; }

/* --- Sample-report cards --- */
.reports { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
.report-card {
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--paper);
  display: flex; flex-direction: column;
  transition: box-shadow .15s, transform .15s;
}
.report-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.report-thumb {
  aspect-ratio: 8.5 / 11; background: var(--paper-deep);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-faint); font-size: .82rem; text-align: center; padding: var(--s4);
  background-image: linear-gradient(180deg, #fff 0%, #fff 22%, var(--paper-tint) 22%);
}
.report-body { padding: var(--s5); flex: 1; display: flex; flex-direction: column; }
.report-body h3 { font-size: 1.03rem; margin-bottom: 6px; }
.report-body p { font-size: .92rem; color: var(--ink-soft); flex: 1; }
.report-meta { font-size: .8rem; color: var(--ink-faint); margin-top: var(--s3); }

/* --- Gate (demo access) --- */
.gate {
  max-width: 460px; margin: 0 auto;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s6); box-shadow: var(--shadow);
}
.gate h2 { font-size: 1.4rem; }
.gate-status { margin-top: var(--s4); font-size: .92rem; min-height: 1.4em; }
.gate-status.err { color: var(--red); font-weight: 600; }
.gate-status.ok  { color: var(--green); font-weight: 600; }

/* --- Call to action band --- */
.cta-band { background: var(--navy-deep); color: #cfd8e6; text-align: center; }
.cta-band h2 { color: #fff; margin-bottom: var(--s4); }
.cta-band p { max-width: 56ch; margin: 0 auto var(--s6); color: #b9c6d8; }

/* --- Long-form prose (legal pages) --- */
.prose h2 { font-size: 1.4rem; margin-top: var(--s7); }
.prose h3 { font-size: 1.08rem; margin-top: var(--s5); }
.prose li { color: var(--ink-soft); }
.prose p { color: var(--ink-soft); }


/* --- Home banner carousel ------------------------------------------------
   A rotating band of iPad screens at the top of the home page. Each slide is
   a .device (the same mock used elsewhere) plus a short caption.

   Slides are stacked in one grid cell and cross-faded, so the band never
   changes height and nothing below it jumps. The script in site.js drives it;
   with JavaScript off, the first slide simply stays put — which is why the
   markup marks slide one as active rather than relying on the script to do it.

   To swap in a real screenshot later: replace the .device block inside a slide
   with <img class="device-shot" src="assets/img/shot-name.png" alt="...">.
   Keep the images 4:3 and at least 1600px wide.                            */
.showcase {
  background:
    radial-gradient(900px 400px at 15% -20%, rgba(44, 111, 173, .35), transparent 60%),
    linear-gradient(180deg, var(--navy-deep), var(--navy));
  color: #fff;
  padding: var(--s8) 0 var(--s7);
}
.showcase .eyebrow { color: #8fb8dd; }
.showcase-head { text-align: center; margin-bottom: var(--s7); }
.showcase-head h2 { color: #fff; max-width: 22ch; margin: 0 auto; font-size: 1.9rem; }

.showcase-stage { display: grid; }
.showcase-slide {
  grid-area: 1 / 1;
  display: grid; grid-template-columns: 1.15fr 1fr;
  gap: var(--s7); align-items: center;
  opacity: 0; visibility: hidden;
  transition: opacity .55s ease;
}
.showcase-slide.is-active { opacity: 1; visibility: visible; }

.showcase-caption h3 { color: #fff; font-size: 1.4rem; margin-bottom: var(--s3); }
.showcase-caption p  { color: #b9c8dc; margin-bottom: 0; }
.showcase-caption .badge { background: rgba(255,255,255,.12); color: #cfe0f2; }

/* A real screenshot, when one is dropped in, sits in the same navy bezel. */
.device-shot {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  background: var(--navy-deep); border: 12px solid var(--navy-deep);
  border-radius: 22px; box-shadow: var(--shadow-lg);
}

/* --- Three shells around the same mock ------------------------------------
   The point of the banner is that this is one interface that reshapes itself,
   so the slides put the same app in a tablet, a phone and a desktop window.
   Only the shell and the aspect ratio change; the mock furniture inside
   (.mock-row, .mock-pill, .mock-doc) is shared by all three.               */

/* Tablet is the default .device — nothing to add. */

.device.phone {
  width: 224px; margin: 0 auto;
  border-radius: 30px; padding: 9px;
}
.device.phone .device-screen { aspect-ratio: 9 / 18; border-radius: 22px; }
.device.phone .device-body { padding: 10px; font-size: .68rem; }
/* The speaker slot. Decorative, so it carries no meaning for a screen reader. */
.device.phone::before {
  content: ""; position: absolute; top: 15px; left: 50%;
  transform: translateX(-50%);
  width: 52px; height: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .22); z-index: 2;
}

.device.desktop { border-radius: 12px; padding: 10px 10px 0; }
.device.desktop .device-screen { aspect-ratio: 16 / 10; border-radius: 6px; }
/* The monitor foot, drawn rather than imaged. */
.device.desktop::after {
  content: ""; display: block; height: 12px; width: 34%;
  margin: 0 auto; border-radius: 0 0 6px 6px;
  background: var(--navy-deep); filter: brightness(.8);
}
/* Two-pane layout — the thing a desktop gets that a phone does not. */
.mock-split { display: grid; grid-template-columns: 84px 1fr; gap: 10px; height: 100%; }
.mock-side { border-right: 1px solid var(--line); padding-right: 8px; }
.mock-side .mock-chip { display: block; margin-bottom: 5px; text-align: center; }
.mock-main { min-width: 0; }

/* --- Carousel controls --- */
.showcase-controls {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s4); margin-top: var(--s6);
}
.showcase-dots { display: flex; gap: var(--s2); }
.showcase-dot {
  width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.28); cursor: pointer;
  transition: background .2s, transform .2s;
}
.showcase-dot:hover { background: rgba(255,255,255,.55); }
.showcase-dot[aria-current="true"] { background: #fff; transform: scale(1.25); }
.showcase-arrow {
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid rgba(255,255,255,.25); border-radius: 50%;
  background: transparent; color: #fff; cursor: pointer; font-size: 1rem;
  line-height: 1; transition: background .2s, border-color .2s;
}
.showcase-arrow:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.5); }
.showcase-dot:focus-visible, .showcase-arrow:focus-visible {
  outline: 2px solid #8fb8dd; outline-offset: 3px;
}

/* --- Extra mock furniture used only by the carousel slides --- */
/* A stand-in for a finished report page. */
.mock-doc { padding: 2px; }
.mock-doc .doc-title { font-weight: 700; color: var(--navy-deep); font-size: .82rem; margin-bottom: 2px; }
.mock-doc .doc-meta  { color: var(--ink-faint); font-size: .66rem; margin-bottom: var(--s3); }
.mock-line { height: 6px; border-radius: 3px; background: var(--paper-deep); margin-bottom: 6px; }
.mock-line.short { width: 55%; }
.mock-line.mid   { width: 78%; }
.mock-figure {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: var(--s3) 0;
}
.mock-figure span {
  aspect-ratio: 4 / 3; border-radius: 4px;
  background: linear-gradient(135deg, var(--paper-deep), #dfe6f0);
  border: 1px solid var(--line);
}
/* A stand-in for the library browser. */
.mock-lib { display: flex; gap: 6px; flex-wrap: wrap; }
.mock-chip {
  font-size: .64rem; font-weight: 600; padding: 4px 9px; border-radius: 999px;
  background: var(--blue-wash); color: var(--blue-dark); border: 1px solid #cfe3f7;
}
/* --- Worked examples (features page) --------------------------------------
   Small figures that show a feature rather than describing it. Each one is a
   <figure>: a light frame holding a drawn mock, with a caption naming the
   feature underneath. Drawn in HTML for the same reason as the hero mock —
   no screenshot to keep in step with the app.                              */
.examples {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--s5); margin-top: var(--s7);
}
.example { margin: 0; }
.example-frame {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: var(--s4); aspect-ratio: 4 / 3; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; gap: 8px;
  /* The mock furniture is drawn at the scale it has inside .device-body.
     Out here it would otherwise inherit body type and overflow the frame. */
  font-size: .74rem;
}
/* A photo or plan fills whatever height the frame has left rather than
   insisting on its own 4:3 and pushing past the bottom edge. */
.example-frame > .mock-photo,
.example-frame > .mock-plan { flex: 1; min-height: 0; aspect-ratio: auto; }
.example-frame .mock-row { margin-bottom: 0; }
.example figcaption { margin-top: var(--s3); font-size: .9rem; color: var(--ink-soft); }
.example figcaption strong {
  display: block; color: var(--navy-deep); font-size: .97rem; margin-bottom: 3px;
}

/* Every status a row can take, in one line. */
.mock-statuses { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }

/* A photograph with annotation drawn over it. */
.mock-photo {
  position: relative; aspect-ratio: 4 / 3; border-radius: 6px;
  background: linear-gradient(135deg, #dfe6f0, var(--paper-deep));
  border: 1px solid var(--line);
}
.mock-photo svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.mock-callout {
  position: absolute; font-size: .6rem; font-weight: 600; white-space: nowrap;
  background: var(--paper); border: 1px solid var(--line);
  padding: 2px 6px; border-radius: 4px; color: var(--ink);
  box-shadow: 0 1px 3px rgba(15,28,48,.12);
}

/* A plan sheet with numbered pins dropped on it. */
.mock-plan {
  position: relative; aspect-ratio: 4 / 3; border-radius: 6px;
  background: var(--paper-tint); border: 1px solid var(--line); overflow: hidden;
}
.mock-plan svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.mock-pin {
  position: absolute; width: 19px; height: 19px; border-radius: 50%;
  display: grid; place-items: center; transform: translate(-50%, -50%);
  font-size: .6rem; font-weight: 700; color: #fff;
  border: 2px solid var(--paper); box-shadow: 0 1px 4px rgba(15,28,48,.3);
}
.mock-pin.red  { background: var(--red); }
.mock-pin.blue { background: var(--blue); }

/* Report pages, seen as thumbnails. */
.mock-pages { display: flex; gap: 9px; align-items: flex-end; justify-content: center; }
.mock-page {
  width: 30%; aspect-ratio: 8.5 / 11; background: var(--paper);
  border: 1px solid var(--line); border-radius: 3px; padding: 7px;
  box-shadow: var(--shadow); font-size: .5rem;
}
.mock-page .mock-line { height: 3px; margin-bottom: 3px; }
.mock-page .page-no {
  color: var(--ink-faint); font-size: .5rem; text-align: center; margin-top: 3px;
}

/* Category tabs with a done-of-total counter. */
.mock-tabs { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; }
.mock-tab {
  font-size: .63rem; font-weight: 600; padding: 4px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink-soft);
}
.mock-tab.done { background: var(--green-wash); color: var(--green); border-color: #bfe3cb; }

/* A numbered test procedure, one line per step. */
.mock-steps { display: flex; flex-direction: column; gap: 5px; }
.mock-step {
  display: flex; align-items: center; gap: 7px; font-size: .64rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 5px 8px;
}
.mock-step .n {
  width: 15px; height: 15px; flex: 0 0 15px; border-radius: 50%;
  background: var(--navy); color: #fff; font-weight: 700;
  display: grid; place-items: center; font-size: .55rem;
}
.mock-step .label { flex: 1; }

/* Visits across the life of a project. */
.mock-visits { display: flex; align-items: stretch; gap: 5px; }
.mock-visit {
  flex: 1; text-align: center; font-size: .58rem; font-weight: 600;
  padding: 6px 2px; border-radius: var(--radius-sm);
  background: var(--paper-tint); border: 1px solid var(--line); color: var(--ink-soft);
}
.mock-visit.now { background: var(--blue-wash); border-color: #cfe3f7; color: var(--blue-dark); }

/* ============ 7. RESPONSIVE ============================================= */

@media (max-width: 900px) {
  .grid-3, .grid-4, .plans, .reports, .stats, .examples { grid-template-columns: repeat(2, 1fr); }
  .split, .split.wide-left, .split.wide-right { grid-template-columns: 1fr; gap: var(--s6); }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--s5); }
  section { padding: var(--s8) 0; }

  .nav-toggle { display: block; }
  .nav-links {
    display: none; position: absolute; top: 68px; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); border-bottom: 1px solid var(--line);
    padding: var(--s3); box-shadow: var(--shadow);
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 12px; }
  .nav-links .btn { margin-top: var(--s2); justify-content: center; }

  /* Carousel: caption drops under the screen. */
  .showcase-slide { grid-template-columns: 1fr; gap: var(--s5); }
  .showcase-head h2 { font-size: 1.6rem; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .grid-2, .grid-3, .grid-4, .plans, .reports, .stats, .examples { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .btn-row .btn { width: 100%; }
  .hero { padding: var(--s8) 0 var(--s7); }
  .plan.featured::after { font-size: .66rem; }
  .showcase { padding: var(--s7) 0 var(--s6); }
  .showcase-head { margin-bottom: var(--s5); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
  /* The script also stops auto-advancing — see site.js. Slides still change
     when the visitor presses a dot or an arrow, they just cut rather than fade. */
}

/* Printing a page should not waste ink on the nav/footer. */
@media print {
  .nav, .footer, .cta-band, .btn { display: none !important; }
  body { font-size: 12pt; }
}

/* ---------- REPORT SCREENSHOTS ----------------------------------------
   Sections lifted straight out of a generated sample report. The frame is
   deliberately plain — a thin rule and a soft shadow — so the report's own
   layout is what the eye lands on. Images are 2x and set to their own
   aspect ratio, so nothing jumps while they load.                        */
.report-fig {
  margin: 0;
}
.report-fig img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--paper);
}
.report-fig figcaption {
  margin-top: var(--s3);
  color: var(--ink-faint);
  font-size: .9rem;
  line-height: 1.5;
}
.report-fig a {
  display: block;
  border: 0;
}
/* One per row on purpose: a report page shrunk into a half-width column is
   a picture of text nobody can read. Full width gets it to about two-thirds
   of print size, and the link opens the picture at full size.            */
.report-gallery {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s8);
  align-items: start;
}
.report-fig .zoom-note {
  color: var(--ink-faint);
  font-size: .85rem;
  white-space: nowrap;
}

/* ---------- HERO CAROUSEL ---------------------------------------------
   The hero's right-hand column cycles: the app drawn in HTML, then sections
   of a report it generated. Slides stack in one grid cell of a fixed shape
   so the column never changes height mid-fade, and the pictures are
   contained inside that shape rather than cropped — a cropped report page
   is a report page with its first line cut off.                          */
.hero-shots { display: block; }
.hero-stage {
  display: grid;
  aspect-ratio: 4 / 3.4;
}
/* One picture fades out before the next fades in, rather than the two
   cross-dissolving through each other: the outgoing slide takes .8s, and the
   incoming one waits that long before it starts. Visibility flips with no
   duration, held back by the same delay so a faded-out slide stays out of the
   tab order until it has actually gone.                                    */
.hero-slide {
  grid-area: 1 / 1;
  display: block;
  align-self: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity .55s ease, visibility 0s linear .55s;
}
.hero-slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .55s ease .55s, visibility 0s linear .55s;
}
.hero-slide > .device { height: 100%; }

.hero-shot { margin: 0; height: 100%; display: flex; flex-direction: column; }
.hero-shot img {
  display: block;
  width: 100%;
  min-height: 0;
  flex: 1 1 auto;
  object-fit: contain;
  object-position: top center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  background: var(--paper);
}
.hero-shot figcaption {
  margin-top: var(--s3);
  color: var(--ink-faint);
  font-size: .85rem;
  text-align: center;
}

/* A photograph of real work is not a document: contained inside the stage it
   would sit in a band of white. These fill a 3:2 frame instead, cropped,
   which is how a photograph wants to be shown. */
.hero-shot--photo img {
  flex: 0 0 auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
}

/* Arrows rather than dots. Nine grey circles said "there is more" without
   saying which way, and an 8px target is unkind on a phone. */
.hero-nav {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s4); margin-top: var(--s4);
}
.hero-arrow {
  width: 34px; height: 34px; display: grid; place-items: center;
  padding: 0; border: 1px solid var(--line); border-radius: 50%;
  background: var(--paper); color: var(--ink-soft); cursor: pointer;
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.hero-arrow:hover {
  background: var(--paper-deep); border-color: var(--ink-faint); color: var(--navy-deep);
}
.hero-arrow:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.hero-count {
  font-size: .82rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; min-width: 3.5em; text-align: center;
}

@media (max-width: 760px) {
  .hero-stage { aspect-ratio: 4 / 3.8; }
}

/* ---------- PHOTOGRAPH BANDS ------------------------------------------
   Real site photographs between the drawn panels, so a page is not wall to
   wall illustration. Wide and shallow on purpose: they break the column up
   without pushing the next section off the screen.                       */
.photo-band {
  margin: var(--s8) 0;
}
.photo-band img {
  display: block;
  width: 100%;
  height: clamp(220px, 34vw, 420px);
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.photo-band figcaption {
  margin-top: var(--s3);
  color: var(--ink-faint);
  font-size: .9rem;
}

/* ---------- A REPORT, PAGE BY PAGE -------------------------------------
   The sample report shown as the document it is rather than as crops: pages
   in order, at a size where the structure reads even if the body text does
   not. Each one opens the real file.                                     */
.report-pages {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s5);
}
.report-page {
  display: block;
  position: relative;
  border: 0;
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--paper);
  transition: transform .15s ease, box-shadow .15s ease;
}
.report-page:hover,
.report-page:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.report-page img { display: block; width: 100%; height: auto; }
.report-page span {
  position: absolute; right: 8px; bottom: 8px;
  min-width: 22px; padding: 1px 6px;
  border-radius: 999px;
  background: rgba(15, 28, 48, .72); color: #fff;
  font-size: .72rem; font-weight: 700; text-align: center;
}

/* The sample-reports card thumbnail, when it holds a real page image. */
.report-thumb-img { padding: 0; display: block; overflow: hidden; }
.report-thumb-img img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }

/* ---------- IIBEC CREDENTIAL BADGES ------------------------------------
   Text badges, not IIBEC's logo artwork: the letters are the author's to
   state, the artwork is the institute's to license. Each badge links to
   IIBEC's own page for that registration, so a visitor who does not know
   what RWC means can find out in one click.                              */
.creds {
  list-style: none;
  margin: var(--s5) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
}
.creds a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s2);
  width: 124px;
  text-decoration: none;
  border: 0;
  transition: transform .15s ease;
}
.creds a:hover,
.creds a:focus-visible { transform: translateY(-2px); }
.creds img { display: block; width: 84px; height: auto; }
.creds span {
  font-size: .72rem;
  line-height: 1.25;
  color: var(--ink-faint);
  text-align: center;
}

@media (max-width: 560px) {
  .creds { gap: var(--s4); justify-content: center; }
  .creds a { width: 104px; }
  .creds img { width: 72px; }
}

/* ---------- PLATFORM OPTIONS, UNDER THE HERO --------------------------
   Names and one line each, linking into the full descriptions on the
   features page. Deliberately not a copy of those descriptions: one place
   to keep true, and the home page stays short.                          */
.platforms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--s4);
}
.platforms .platform {
  display: block;
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.platforms .platform:hover,
.platforms .platform:focus-visible {
  border-color: var(--blue);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.platforms .platform strong {
  display: block;
  color: var(--navy-deep);
  font-size: 1rem;
  margin-bottom: 2px;
}
.platforms .platform span {
  display: block;
  color: var(--ink-faint);
  font-size: .86rem;
  line-height: 1.45;
}
.platforms .platform em {
  display: inline-block;
  margin-top: var(--s2);
  font-style: normal;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #9c5c00;
  background: var(--amber-wash);
  padding: 2px 8px;
  border-radius: 999px;
}


/* --- Real screenshots (2026-10-07) ---------------------------------------
   The drawn device mock-ups were replaced with screenshots of the actual app,
   taken from the fictional Harborview sample visit (SIP edition) at iPad
   size (1180 x 820, 2x) and phone size (390 x 844, 3x). The bezel is a plain
   dark border, not a drawing of a device - the screen is the point.        */
.shot-tablet, .shot-phone {
  display: block; height: auto; background: var(--navy-deep);
  border: 10px solid #111827; box-shadow: var(--shadow-lg);
}
.shot-tablet { width: 100%; border-radius: 20px; }
.shot-phone  { width: 100%; border-radius: 28px; border-width: 7px; }
.shot-pair { position: relative; padding-right: 13%; padding-bottom: 6%; }
.shot-pair .shot-phone {
  position: absolute; right: 0; bottom: 0; width: 27%;
}
@media (max-width: 640px) {
  .shot-pair { padding-right: 0; padding-bottom: 0; }
  .shot-pair .shot-phone { display: none; }   /* on a phone, the phone shot inside a phone is clutter */
}




/* The hero's closing line: why a small company is better at this than a
   large one. Fine-print size so it does not fight the headline, but the
   second sentence is full-strength ink because it is the argument. */
.hero-credit {
  margin-top: var(--s4);
  font-size: .88rem;
  line-height: 1.55;
  color: var(--ink-faint);
  max-width: 46ch;
}
.hero-credit strong { color: var(--navy-deep); font-weight: 700; }


/* --- Real Hub captures -------------------------------------------------
   Browser screenshots are 16:10, not the 4:3 the drawn mocks in
   .example-frame assume, so this grid sets its own shape. Each links to the
   full-size image because a developer will want to read the numbers. */
.hub-shots img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); background: var(--paper);
  transition: box-shadow .2s ease, transform .2s ease;
}
.hub-shots a:hover img { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.hub-shots a:focus-visible img { outline: 2px solid var(--blue); outline-offset: 3px; }


/* --- A list that reveals on a stagger ----------------------------------
   The items are VISIBLE as written. Script adds .is-armed to the list to
   apply the hidden start state, then .is-in to play it - so a reader with
   no JavaScript, or one who has asked for less motion, gets a plain list
   rather than an empty box. That ordering is the whole trick: never hide
   content in CSS and rely on script to bring it back. */
.reveal-list {
  list-style: none; padding: 0;
  margin: var(--s5) auto var(--s6);
  display: grid; gap: var(--s3);
  /* Sets its own alignment: it may be dropped inside a centred section head,
     and a list is read down its left edge. */
  text-align: left;
  max-width: 68ch;
}
.reveal-list li {
  display: grid; gap: 2px;
  padding-left: var(--s5); position: relative;
  line-height: 1.5;
}
.reveal-list li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--blue);
}
.reveal-list strong { color: var(--navy-deep); }
.reveal-list span { color: var(--ink-soft); font-size: .93rem; }

.reveal-list.is-armed li {
  opacity: 0; transform: translateY(8px);
  transition: opacity .45s ease, transform .45s ease;
}
.reveal-list.is-armed.is-in li { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal-list.is-armed li { opacity: 1; transform: none; transition: none; }
}

@media (max-width: 760px) {
  .reveal-list { gap: var(--s4); }
}


/* The pinned-conflict capture. Wide and shallow - it is a single row from
   the Hub, not a page - so it sits full width rather than in the grid. */
.pinboard-shot { margin: var(--s6) 0 0; }
.pinboard-shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.pinboard-shot figcaption {
  margin-top: var(--s3); font-size: .9rem; color: var(--ink-soft);
  text-align: center; max-width: 62ch; margin-left: auto; margin-right: auto;
}


/* --- Two photographs side by side --------------------------------------
   Used for the two cities on the developers page. Each is a .photo-band, so
   the frame, radius and caption styling are already right; this only sets
   them beside each other and stacks them on a phone. */
.photo-pair {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5);
  margin-top: var(--s6);
}
.photo-pair .photo-band { margin: 0; }
/* Half the width, so half the vw term - otherwise each keeps a full-width
   height on half the space and crops to a letterbox. */
.photo-pair .photo-band img { height: clamp(180px, 17vw, 300px); }
.photo-pair figcaption {
  text-align: center; font-weight: 600; color: var(--navy-deep);
}
.pair-note {
  margin: var(--s4) auto 0; max-width: 64ch; text-align: center;
  font-size: .92rem; color: var(--ink-soft);
}
.pair-note strong { color: var(--navy-deep); }

@media (max-width: 760px) {
  .photo-pair { grid-template-columns: 1fr; gap: var(--s4); }
}


/* --- Two co-equal hero claims ------------------------------------------
   The app and the owner side are the two halves of the product, so they are
   set identically: same size, same colour, same spacing, no divider. The
   only thing separating them is the order you read them in. Previously the
   second one was smaller, lighter and under a rule, which is the typography
   of a footnote. */
.hero-claims { display: grid; gap: var(--s5); margin-bottom: var(--s6); }
.hero-claims p {
  font-size: 1.19rem;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 52ch;
  margin: 0;
}
.hero-claims strong { color: var(--navy-deep); }
.hero-claims a { white-space: nowrap; }

@media (max-width: 760px) {
  .hero-claims p { font-size: 1.06rem; }
}


/* --- Floating contact --------------------------------------------------
   One tap to the contact page from anywhere. z-index 90 keeps it under the
   header (100) and the skip link, so it can never cover the menu. It is a
   plain link, so it works with no JavaScript and tabs in normal order. */
.float-contact {
  position: fixed; right: var(--s5); bottom: var(--s5); z-index: 90;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px var(--s5);
  background: var(--paper); color: var(--navy-deep); text-decoration: none;
  border: 1px solid var(--line);
  font-size: .95rem; font-weight: 600; line-height: 1;
  border-radius: 999px; box-shadow: var(--shadow);
  transition: background .2s ease, transform .2s ease, opacity .25s ease,
              visibility 0s linear 0s;
}
.float-contact:hover { background: var(--paper-deep); transform: translateY(-2px); color: var(--navy-deep); }
.float-contact:focus-visible { outline: 3px solid #8fb8dd; outline-offset: 3px; }

/* Out of the way once the footer is in view, so it never sits on top of the
   final call to action - which on a phone is exactly where it would land. */
.float-contact.is-away {
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .25s ease, transform .25s ease, visibility 0s linear .25s;
}

@media (max-width: 760px) {
  .float-contact {
    right: var(--s4); bottom: var(--s4);
    padding: 11px var(--s4); font-size: .9rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .float-contact { transition: none; }
  .float-contact:hover { transform: none; }
}

@media print { .float-contact { display: none; } }


/* --- Floating trial, bottom-left ---------------------------------------
   The primary of the two floating buttons: solid, in brand blue, opposite
   corner from contact, which is now a quieter outline. Different weights
   so the pair reads as primary and secondary rather than competing. It
   shares [data-float-contact] so the same observer hides both at the
   footer. */
.float-trial {
  position: fixed; left: var(--s5); bottom: var(--s5); z-index: 90;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px var(--s5);
  background: var(--blue); color: #fff; text-decoration: none;
  font-size: .95rem; font-weight: 700; line-height: 1;
  border-radius: 999px; box-shadow: var(--shadow-lg);
  transition: background .2s ease, transform .2s ease, opacity .25s ease,
              visibility 0s linear 0s;
}
.float-trial:hover { background: var(--navy-deep); transform: translateY(-2px); color: #fff; }
.float-trial:focus-visible { outline: 3px solid #8fb8dd; outline-offset: 3px; }
.float-trial.is-away {
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .25s ease, transform .25s ease, visibility 0s linear .25s;
}

@media (max-width: 760px) {
  .float-trial { left: var(--s4); bottom: var(--s4); padding: 12px var(--s4); font-size: .9rem; }
}

/* Too narrow for two labelled pills side by side: contact keeps the icon
   and loses the words, and the label stays for screen readers. */
@media (max-width: 560px) {
  .float-contact { padding: 12px; }
  .float-contact span {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {
  .float-trial { transition: none; }
  .float-trial:hover { transform: none; }
}

@media print { .float-trial { display: none; } }


/* --- A real filing path -------------------------------------------------
   Set as a path rather than a sentence, because the whole point is that a
   buyer can picture the folder. Monospace, wrapping allowed - the filename
   is long on purpose and truncating it would hide the argument. */
.filing-example {
  margin: var(--s5) 0 0;
  padding: var(--s5);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.filing-example code {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .86rem;
  line-height: 1.6;
  color: var(--ink-faint);
  word-break: break-word;
}
.filing-example code.file {
  color: var(--navy-deep);
  font-weight: 600;
  padding-left: var(--s4);
}
.filing-example figcaption {
  margin-top: var(--s4);
  font-size: .86rem;
  color: var(--ink-faint);
}
.filing-example figcaption code {
  display: inline; font-size: .84rem; color: var(--ink-soft);
}

@media (max-width: 560px) {
  .filing-example code { font-size: .78rem; }
  .filing-example code.file { padding-left: var(--s3); }
}


/* A heading that separates groups inside one catalogue section - the heads,
   then the replacement parts - without starting a new section each time. */
.cat-head {
  margin: var(--s7) 0 var(--s4);
  font-size: 1.05rem;
  color: var(--navy-deep);
  text-align: center;
}


/* --- Floating buttons: a bottom bar wherever a pill would cover content ------
   The content column is 1140px wide. A pill in a corner only clears it when the
   viewport leaves at least a pill's width plus its margin on each side, which is
   about 1580px. Below that the two buttons dock as one full-width bar at the
   bottom of the viewport, the body reserves the bar's height, and the bar stays
   put at the footer (nothing is under it, so it never covers the closing call to
   action). Above that width the pills keep their corners and still step away at
   the footer. Added 2026-10-31 after the pill was found sitting on the hero text
   at 800px. */
@media (max-width: 1579px) {
  body:has([data-float-contact]) { padding-bottom: 56px; }   /* only pages that carry the buttons (contact.html has none) */
  .float-trial, .float-contact {
    position: fixed; top: auto; bottom: 0; z-index: 90;
    height: 56px; padding: 0 var(--s3); margin: 0;
    border-radius: 0; justify-content: center;
    box-shadow: 0 -2px 10px rgba(15, 23, 42, .10);
    font-size: .95rem; transform: none;
  }
  .float-trial { left: 0; right: 50%; border-top: 1px solid var(--blue); }
  .float-contact { left: 50%; right: 0; border: 0; border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
  .float-trial:hover, .float-contact:hover { transform: none; }
  .float-trial.is-away, .float-contact.is-away { opacity: 1; visibility: visible; transform: none; }
  /* the contact label comes back: half the width is room enough for two words */
  .float-contact span { position: static; width: auto; height: auto; overflow: visible; clip: auto; clip-path: none; white-space: nowrap; }
}
@media print { .float-trial { display: none; } body:has([data-float-contact]) { padding-bottom: 0; } }
