/* =============================================================================
   Salty Boat Care — design tokens and shell styles.

   Hand-rolled rather than Bootstrap: the brief asks for a restrained, generous
   layout on a fixed palette, and the page furniture here is a header, a footer,
   plan cards and accordions. Bootstrap's reboot would have to be overridden more
   than it is used, and dropping it takes ~230 KB of CSS and jQuery off a
   mobile-first site whose traffic arrives by phone.

   Page-level styles arrive with their pages (V4-V10).
   ============================================================================= */

/* --- Fonts ----------------------------------------------------------------
   Self-hosted from /fonts, never fetched from Google Fonts or any other CDN.
   That is a GDPR rule, not a performance preference: a font request hands the
   visitor's IP address to a third party before the page has asked for any
   consent, which is what the Munich district court decided against in 2022.
   See wwwroot/fonts/README.md for where these files come from.

   Variable faces, so one file per family covers every weight the design uses
   (400, 500, 600, 700 and 800 on the wordmark) instead of five static files.

   Split by unicode-range: Spanish, German and Catalan are all inside "latin",
   so latin-ext is only fetched if a page ever renders a character outside it —
   a name from further east in a future testimonial, say. Declaring it costs
   nothing until that happens.

   No italic face is shipped. Nothing in the design sets font-style: italic, and
   if editorial copy ever introduces an <em>, the browser slants the upright —
   acceptable, and cheaper than two more files. Add the real italics if it
   becomes visible.

   font-display: swap, paired with the preload in _Layout: text is readable
   immediately in the fallback stack and reflows once, rather than being
   invisible while the font loads.
   -------------------------------------------------------------------------- */

@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/fonts/manrope-latin-var.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
        U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/fonts/manrope-latin-ext-var.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
        U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/fonts/inter-latin-var.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
        U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/fonts/inter-latin-ext-var.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
        U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Palette — fixed by the brief. The three status colours are reserved for
       Boat Report statuses and must not be reused as general accents. */
    --color-navy: #0B1F33;
    --color-marine-blue: #1E5A78;
    --color-sand: #D5C5A3;
    --color-off-white: #F5F3EE;
    --color-status-good: #2E7D68;
    --color-status-attention: #D79B36;
    --color-status-action: #B34A3C;

    --color-white: #FFFFFF;
    --color-text: var(--color-navy);
    --color-text-muted: #4A5C6B;
    --color-border: #DCD9D2;

    /* Self-hosted (see the @font-face block above). The system stack stays behind
       each name: it is what renders during the swap, and what a visitor sees if
       the font request fails or a glyph falls outside the subsets shipped. */
    --font-heading: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-body: "Inter", "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    --space-2xs: 0.25rem;
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1.25rem;
    --space-lg: 2rem;
    --space-xl: 3rem;
    --space-2xl: 4.5rem;

    --radius: 6px;
    --header-height: 4rem;
    --content-max: 72rem;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--font-body);
    /* Generous spacing and short paragraphs; avoid dense walls of text. */
    font-size: 1rem;
    line-height: 1.65;
    color: var(--color-text);
    background: var(--color-white);
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    line-height: 1.2;
    /* Sentence case; no all-caps nautical styling. */
    margin: 0 0 var(--space-md);
}

h1 { font-size: clamp(1.9rem, 1.4rem + 2.2vw, 2.9rem); }
h2 { font-size: clamp(1.4rem, 1.2rem + 1vw, 2rem); }

p { margin: 0 0 var(--space-md); }

a {
    color: var(--color-marine-blue);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.15em;
}

ul { margin: 0; padding: 0; }

img { max-width: 100%; height: auto; }

/* Every interactive control shows a clear focus ring: the brief requires full
   keyboard access to buttons, accordions and language controls. */
:focus-visible {
    outline: 3px solid var(--color-marine-blue);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Removed from the page visually but still announced by screen readers — used for
   labels that a sighted user reads from context, such as the menu button's icon. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --- Skip link ------------------------------------------------------------ */

.skip-link {
    position: absolute;
    left: var(--space-xs);
    top: -100%;
    z-index: 100;
    padding: var(--space-xs) var(--space-md);
    background: var(--color-navy);
    color: var(--color-white);
    border-radius: var(--radius);
    text-decoration: none;
}

.skip-link:focus {
    top: var(--space-xs);
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    /* 44px minimum touch target. */
    min-height: 2.75rem;
    padding: var(--space-xs) var(--space-md);
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}

.btn--primary {
    background: var(--color-marine-blue);
    color: var(--color-white);
}

.btn--primary:hover {
    background: var(--color-navy);
}

.btn--ghost {
    background: transparent;
    color: var(--color-navy);
    border-color: var(--color-border);
}

.btn--ghost:hover {
    border-color: var(--color-marine-blue);
    color: var(--color-marine-blue);
}

/* --- Brand wordmark ------------------------------------------------------- */

/* The mark plus the wordmark: "SALTY" heavier, "BOAT CARE" lighter and smaller.
   Restrained by design — no anchors, wheels or crests.

   The wordmark is real text rather than part of the drawing, so it is selectable,
   searchable, and renders at the reader's own font size. */
.brand {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4ch;
    font-family: var(--font-heading);
    color: var(--color-navy);
    text-decoration: none;
    white-space: nowrap;
}

/* The two words align to each other's baseline; the drawing has no baseline worth
   aligning to, so it opts out and centres instead.

   It was hidden below 40rem: on a 375px phone its 43px pushed the menu button onto a
   second row and took the header from 64px to 93px. What made the row that tight was
   the language switcher sitting in it; that moved into the menu panel, and the mark
   and the button now share one line down to 320px. */
.brand__mark {
    display: block;
    align-self: center;
    height: 1.85rem;
    width: auto;
    margin-right: 0.2ch;
    /* currentColor in the artwork means the mark simply follows the text. */
    color: inherit;
    flex-shrink: 0;
}

.brand__strong {
    font-weight: 800;
    font-size: 1.15rem;
    letter-spacing: 0.02em;
}

.brand__light {
    font-weight: 400;
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    color: var(--color-marine-blue);
}

/* Set on the container, not only on the spans, so the mark's currentColor flips too. */
.brand--footer,
.brand--footer .brand__strong,
.brand--footer .brand__light { color: var(--color-off-white); }

/* --- Header --------------------------------------------------------------- */

.site-header {
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    /* The compact row is the brand and the menu button. The language switcher moved
       into the menu panel: on a phone it was the third thing competing for a row that
       wraps below 375px, and it is one tap away in the menu instead. */
    gap: var(--space-sm);
    max-width: var(--content-max);
    min-height: var(--header-height);
    margin: 0 auto;
    padding: 0 var(--space-md);
}

/* Small screens: logo · language selector · menu, with the nav panel dropping below.
   The order properties are what let one language switcher serve both layouts. */
.brand { order: 1; }
.nav-toggle { order: 2; margin-left: auto; }
.site-header__collapse { order: 3; }
.site-header__actions { order: 4; }

/* Sticky only once the visitor starts scrolling, and compact when it is —
   site.js adds the class, so the header takes no space at the top of the page. */
.header-stuck .site-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
    box-shadow: 0 1px 12px rgba(11, 31, 51, 0.1);
    animation: header-drop 160ms ease-out;
}

.header-stuck body { padding-top: var(--header-height); }

@keyframes header-drop {
    from { transform: translateY(-100%); }
    to { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .header-stuck .site-header { animation: none; }
    .btn { transition: none; }
}

.site-header__collapse {
    display: none;
    flex: 1;
}

.site-header__collapse.is-open {
    display: block;
    flex-basis: 100%;
    padding-bottom: var(--space-md);
}

.site-header__collapse .lang--header {
    margin-top: var(--space-sm);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--color-border);
}

.site-nav__list,
.site-header__actions {
    list-style: none;
}

.site-nav__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    margin: 0 0 var(--space-md);
}

.site-nav__link {
    display: block;
    padding: var(--space-xs) 0;
    color: var(--color-navy);
    font-family: var(--font-heading);
    font-size: 0.95rem;
    text-decoration: none;
}

.site-nav__link:hover { color: var(--color-marine-blue); }

.site-nav__link--current {
    color: var(--color-marine-blue);
    /* Not colour alone: the current page also carries a visible marker and
       aria-current for assistive technology. */
    box-shadow: inset 0 -2px 0 var(--color-marine-blue);
}

/* Hidden on phones: the bottom action bar carries these two actions instead, so they
   never appear twice on the same screen. */
.site-header__actions {
    display: none;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
}

/* --- Menu toggle (mobile) ------------------------------------------------- */

.nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    /* Square icon button: the visible word would push the compact header onto a
       second row on a 375px screen. The accessible name is kept in a hidden span. */
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: var(--space-xs);
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-family: var(--font-heading);
    font-size: 0.9rem;
    color: var(--color-navy);
    cursor: pointer;
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
    display: block;
    width: 1.1rem;
    height: 2px;
    background: currentColor;
    content: "";
}

.nav-toggle__bars {
    position: relative;
}

.nav-toggle__bars::before { position: absolute; top: -6px; }
.nav-toggle__bars::after { position: absolute; top: 6px; }

/* --- Language switcher ---------------------------------------------------- */

.lang__list {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    list-style: none;
}

/* Without a rule between them the three codes read as one string. Absolutely positioned in
   the existing 4px gap, so it costs no width — German has only about 17px of slack — and
   currentColor makes one declaration work on white and on navy. */
.lang__item + .lang__item { position: relative; }

.lang__item + .lang__item::before {
    content: "";
    position: absolute;
    left: -2px;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 0.95em;
    background: currentColor;
    opacity: 0.4;
}

.lang__link {
    display: inline-block;
    /* Tighter horizontally only: that padding bought nothing but width in the row with least
       of it. 33px becomes 25px, still over the 24px target minimum. */
    padding: var(--space-xs) var(--space-2xs);
    font-family: var(--font-heading);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    text-decoration: none;
}

.lang__link:hover { color: var(--color-marine-blue); }

.lang__link--current {
    color: var(--color-navy);
    text-decoration: underline;
    text-underline-offset: 0.3em;
}

.lang--footer .lang__link { color: var(--color-off-white); }
.lang--footer .lang__link--current { color: var(--color-sand); }

/* --- Mobile bottom action bar --------------------------------------------- */

/* Persistent rather than a pop-up: it sits in normal reading order at the end of
   the document, never covers content, and the two conversions stay one tap away
   on the phones most advertising traffic arrives on. */
.action-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    display: flex;
    gap: var(--space-xs);
    padding: var(--space-xs);
    /* Clears the iOS home indicator. */
    padding-bottom: calc(var(--space-xs) + env(safe-area-inset-bottom, 0px));
    background: var(--color-white);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 12px rgba(11, 31, 51, 0.08);
}

.action-bar__item {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-height: 2.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-navy);
    text-decoration: none;
}

.action-bar__item--primary {
    background: var(--color-marine-blue);
    border-color: var(--color-marine-blue);
    color: var(--color-white);
}

/* Reserve the bar's height so it never hides the footer or the last line of a page. */
body { padding-bottom: 4.25rem; }

/* --- Main ----------------------------------------------------------------- */

/*
    A grid rather than a centred max-width box, so a section can run edge to edge while
    everything else stays in the measure. Children are placed in the middle column by
    default and opt into the full width with .bleed.

    Deliberately not the usual `margin-inline: calc(50% - 50vw)` trick: 50vw includes the
    scrollbar, which puts a horizontal scrollbar on the page at exactly the widths Q6 spent
    its time removing. This has no viewport units in it at all.
*/
.site-main {
    display: grid;
    grid-template-columns:
        [full-start] minmax(var(--space-md), 1fr)
        [content-start] minmax(0, var(--content-max)) [content-end]
        minmax(var(--space-md), 1fr) [full-end];
    padding: var(--space-xl) 0 var(--space-2xl);
}

.site-main > * { grid-column: content; }

.bleed {
    grid-column: full;
    /* Its own children come back into the measure. */
    display: grid;
    grid-template-columns: inherit;
}

.bleed > * { grid-column: content; }

/* main pads itself, which leaves a white strip above a page that opens in navy and below one
   that closes in it. Pulled back only for those: a page starting or ending in copy still
   wants the space. */
.site-main > .bleed:first-child { margin-top: calc(var(--space-xl) * -1); }
.site-main > .bleed:last-child { margin-bottom: calc(var(--space-2xl) * -1); }

/* --- Home page ------------------------------------------------------------ */

.hero__actions,
.band__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin: var(--space-lg) 0 var(--space-sm);
}

.hero__microcopy {
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.section { margin-bottom: var(--space-2xl); }

.band__text { max-width: 46rem; }

/* Headings are not capped and sections are not split into columns. Both were tried: a 46rem
   cap so a heading ended level with its intro, and a two-column layout so the section filled
   its width. Measured at 1440, the columns give a heading 491px — and this copy is Spanish
   sentences: "Estar lejos de tu barco no debería significar perder el control." needs 938px
   to stay on one line, "Cuidado profesional, comunicación directa" 665, and "Boat Care en el
   norte de Mallorca" 508 — so all three wrapped, the last one for the sake of 17px.

   A heading that wraps to three lines costs more than a paragraph that ends short of the
   right edge. The heading fills its container and breaks only when the words genuinely do
   not fit; .band__text keeps its readable measure underneath. */

.cols {
    display: grid;
    gap: var(--space-lg);
}

/* Paragraphs carry a bottom margin, not a top one, so anything following a grid sits
   straight on it — which is how the "compare all plans" button ended up touching the
   cards above it. */
.cols + p { margin-top: var(--space-xl); }

/* --- Decorative line icons ------------------------------------------------ */

/* Drawn at the brand mark's weight and coloured by currentColor, so one drawing is
   marine blue on white and sand on a navy band with no second rule.

   Shown at every width, phones included. That costs about 150px of scrolling in the trust
   strip on a phone, which is a real price on the screens where vertical space is
   scarcest — taken deliberately, because the icons are what make the page friendly on
   exactly the screens most of its traffic arrives on. */
.icon {
    display: block;
    width: 1.75rem;
    height: 1.75rem;
    margin-bottom: var(--space-xs);
    color: var(--color-marine-blue);
    flex-shrink: 0;
}

/* The trust cells centre their text, and a block-level svg does not follow text-align. */
.trust-grid .icon { margin-inline: auto; }
.band-dark .icon { color: var(--color-sand); }

/* Beside a word rather than above it: the icon takes the button's own colour and size,
   so it is off-white on an outline button and navy on a ghost one without knowing which. */
.btn .icon,
.action-bar__item .icon {
    width: 1.15em;
    height: 1.15em;
    margin-bottom: 0;
    color: inherit;
}

/* WhatsApp's own green, which is what their guidelines ask for when the glyph is used in
   colour. A literal rather than a token: the tokens are this brand's palette, and putting
   somebody else's brand colour among them would invite it being reused as one of ours. */
.btn .icon--whatsapp,
.action-bar__item .icon--whatsapp { color: #25D366; }

.cols__title {
    margin-bottom: var(--space-xs);
    font-size: 1.05rem;
    color: var(--color-marine-blue);
}

.steps {
    display: grid;
    gap: var(--space-sm);
    margin: 0;
    padding-left: 1.4em;
    max-width: 46rem;
}

.steps li { padding-left: var(--space-2xs); }

.report-block {
    display: grid;
    gap: var(--space-lg);
    align-items: start;
}

/*
    Wide content scrolls inside its own box rather than pushing the page sideways. Measured:
    the status legend is three columns of text that cannot compress below about 389px, so at
    360px — which is most Android phones — it gave the whole home page a horizontal scrollbar.

    Always paired with tabindex="0", role="region" and an aria-label in the markup: a
    scrollable region that cannot be focused cannot be scrolled by keyboard, and one without
    a name is announced as an unlabelled region.
*/
.table-scroll { overflow-x: auto; }

.legend {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.legend th,
.legend td {
    padding: var(--space-xs) var(--space-sm);
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border);
}

.legend thead th {
    font-family: var(--font-heading);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.plan-teaser {
    padding: var(--space-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.plan-teaser--recommended {
    border-color: var(--color-marine-blue);
    border-width: 2px;
}

.plan-teaser__name {
    margin-bottom: var(--space-xs);
    font-size: 1.1rem;
}

.plan-teaser__visits {
    margin: 0 0 var(--space-xs);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.plan-teaser__summary {
    margin: 0;
    font-size: 0.95rem;
}

/* --- Contact form --------------------------------------------------------- */

.contact {
    display: grid;
    gap: var(--space-xl);
    margin-bottom: var(--space-2xl);
}

.form { max-width: 34rem; }

.form__note {
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.form__field { margin-bottom: var(--space-md); }

.form__field label {
    display: block;
    margin-bottom: var(--space-2xs);
    font-family: var(--font-heading);
    font-size: 0.9rem;
    font-weight: 600;
}

.form__field input,
.form__field select,
.form__field textarea {
    width: 100%;
    /* 44px tall and 16px text: anything smaller makes iOS zoom on focus. */
    min-height: 2.75rem;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-white);
    font-family: inherit;
    font-size: 1rem;
    color: var(--color-text);
}

.form__field textarea {
    min-height: 7rem;
    resize: vertical;
}

.form__field--check {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-xs);
    align-items: start;
}

/* Measured at 18x18 on a phone, which is under the 24px target minimum — on the required
   consent box of the site's only conversion, and a checkbox has no forgiving hit area
   around it the way a link in a sentence does. 1.5rem is 24px at the default root size. */
.form__field--check input {
    width: 1.5rem;
    min-height: 1.5rem;
    height: 1.5rem;
    margin-top: 0.15rem;
}

.form__field--check label {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.95rem;
}

.form__optional {
    font-weight: 400;
    color: var(--color-text-muted);
}

.form__error {
    display: block;
    margin-top: var(--space-2xs);
    font-size: 0.85rem;
    /* Not colour alone: the message itself names the problem. */
    color: var(--color-status-action);
}

/* Off-screen rather than display:none — some bots skip hidden inputs, and this one is
   meant to be filled by them. */
.form__honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.notice {
    margin-bottom: var(--space-lg);
    padding: var(--space-md);
    border-left: 3px solid var(--color-marine-blue);
    border-radius: var(--radius);
    background: var(--color-off-white);
}

.notice--success { border-left-color: var(--color-status-good); }

.notice--error { border-left-color: var(--color-status-action); }

.notice ul {
    margin: var(--space-xs) 0 0;
    padding-left: 1.2em;
    font-size: 0.9rem;
}

.contact__aside {
    padding: var(--space-lg);
    border-radius: var(--radius);
    background: var(--color-off-white);
    align-self: start;
}

.contact__aside h2 {
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-bottom: var(--space-xs);
}

.contact__details { margin-bottom: var(--space-lg); }

/* Standalone links, not links inside a sentence, so WCAG 2.2's inline exception does not
   cover them: measured at 19px tall on a phone. The padding takes them past 24px, which
   matters most here — a thumb reaching for "phone" or "WhatsApp" on the contact page. */
.contact__details a {
    color: var(--color-marine-blue);
    display: inline-block;
    padding-block: 0.2rem;
}

/* --- Boat Care scope table ------------------------------------------------ */

/* Two columns of prose rather than short price cells, so these wrap. */
.scope-table td { white-space: normal; }
.scope-table th { width: 50%; }

/* --- Services ------------------------------------------------------------- */

.services {
    display: grid;
    gap: var(--space-lg);
    margin-bottom: var(--space-2xl);
}

.service {
    max-width: 46rem;
    padding: var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.service__name {
    margin-bottom: var(--space-xs);
    font-size: 1.25rem;
}

.service__description { max-width: 42rem; }

.service__pricing {
    margin: var(--space-md) 0 0;
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

/* The coordination caveat. Sand-accented and inline rather than tucked into a
   footnote: it is the line that keeps the offer honest. */
.service__important {
    display: block;
    margin-top: var(--space-md);
    padding: var(--space-md);
    border-left: 3px solid var(--color-sand);
    background: var(--color-off-white);
    font-size: 0.9rem;
}

.service__important-label {
    display: block;
    margin-bottom: var(--space-2xs);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.service__cta { margin-top: var(--space-md); }

/* --- FAQ ------------------------------------------------------------------ */

.faq {
    max-width: 46rem;
    margin-bottom: var(--space-2xl);
    border-top: 1px solid var(--color-border);
}

.faq__item { border-bottom: 1px solid var(--color-border); }

.faq__question {
    /* A generous target: this is the page's main control and most traffic is on a phone. */
    padding: var(--space-md) var(--space-xs);
    cursor: pointer;
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-navy);
}

.faq__question:hover { color: var(--color-marine-blue); }

.faq__answer {
    padding: 0 var(--space-xs) var(--space-md);
    max-width: 42rem;
}

.faq__answer p { margin: 0; }

/* --- Boat Report ---------------------------------------------------------- */

/* The report is the service's differentiator, so it is rendered as a report rather
   than represented by a document icon. */
.report {
    max-width: 34rem;
    margin: 0 0 var(--space-xl);
    padding: var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-white);
    box-shadow: 0 2px 16px rgba(11, 31, 51, 0.06);
}

/* Marked as a sample, always. It shows a named boat at a named marina, and must never
   be mistaken for a real client's report. */
.report__example {
    display: inline-block;
    margin-bottom: var(--space-sm);
    padding: 0.15em 0.6em;
    border: 1px dashed var(--color-border);
    border-radius: 999px;
    font-size: 0.75rem; /* 12px floor: below that these labels stop being comfortably legible on a phone. */
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.report__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--color-border);
}

.report__title {
    margin: 0;
    font-size: 1.25rem;
}

.report__overall {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    margin: 0;
}

.report__overall-label {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* The status chip carries colour AND the written label. The three colours below are
   reserved for exactly this and must not be reused as general accents. Foreground
   colours are chosen per background for contrast — amber takes navy text, because
   white on amber falls well under the contrast floor. */
.status {
    display: inline-block;
    padding: 0.2em 0.7em;
    border-radius: 999px;
    font-family: var(--font-heading);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

/* The chip carries the status label, which is the half of the pairing that must not depend
   on colour -- so it has to stay readable. 0.65rem measured 10.4px on a phone. */
.status--small { font-size: 0.75rem; }

.status-good {
    background: var(--color-status-good);
    color: var(--color-white);
}

.status-attention {
    background: var(--color-status-attention);
    color: var(--color-navy);
}

.status-action {
    background: var(--color-status-action);
    color: var(--color-white);
}

.report__meta {
    display: grid;
    gap: var(--space-xs) var(--space-md);
    margin: var(--space-md) 0;
}

.report__meta-item {
    display: flex;
    gap: var(--space-xs);
    font-size: 0.9rem;
}

.report__meta dt {
    color: var(--color-text-muted);
    min-width: 7rem;
}

.report__meta dd {
    margin: 0;
    font-weight: 600;
}

.report__lines {
    list-style: none;
    display: grid;
    gap: var(--space-2xs);
    margin: 0 0 var(--space-md);
}

.report__line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) 0;
    border-bottom: 1px solid var(--color-off-white);
    font-size: 0.95rem;
}

.report__line-label {
    /* Wide enough for the longest label ("Batería de servicios") on one line. */
    flex: 0 0 10rem;
    color: var(--color-text-muted);
}

.report__line-value {
    flex: 1;
    min-width: 8rem;
}

.report__recommendation {
    margin: 0;
    padding: var(--space-md);
    border-left: 3px solid var(--color-marine-blue);
    background: var(--color-off-white);
    font-size: 0.95rem;
}

.report__recommendation-label {
    display: block;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

@media@media (min-width: 40rem) {
    .report__meta { grid-template-columns: 1fr 1fr; }
}

/* --- Plans page ----------------------------------------------------------- */

.hero { margin-bottom: var(--space-xl); }

.hero__intro {
    max-width: 44rem;
    font-size: 1.1rem;
    color: var(--color-text-muted);
}

.badge {
    display: inline-block;
    margin-left: var(--space-xs);
    padding: 0.15em 0.6em;
    border-radius: 999px;
    background: var(--color-sand);
    color: var(--color-navy);
    font-family: var(--font-heading);
    font-size: 0.75rem; /* 12px floor, as above. */
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    vertical-align: middle;
}

.price-matrix { margin-bottom: var(--space-2xl); }

/* The table scrolls inside its own container rather than being swapped for a
   different mobile rendering: the prices stay one crawlable server-rendered table.
   tabindex makes the scrollable region reachable by keyboard. */
.price-matrix__scroll {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.price-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.price-table th,
.price-table td {
    padding: var(--space-sm) var(--space-md);
    text-align: left;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.price-table thead th {
    font-family: var(--font-heading);
    background: var(--color-off-white);
}

.price-table tbody th { font-weight: 500; }

.price-table tbody tr:last-child th,
.price-table tbody tr:last-child td { border-bottom: 0; }

.price-table__col--recommended {
    background: rgba(30, 90, 120, 0.06);
    font-weight: 600;
}

.price-matrix__note {
    margin-top: var(--space-sm);
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.plans {
    display: grid;
    gap: var(--space-lg);
    margin-bottom: var(--space-2xl);
}

.plan-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-white);
}

/* Marked as well as ordered first — the badge carries the meaning, the border is
   only reinforcement. */
.plan-card--recommended {
    border-color: var(--color-marine-blue);
    border-width: 2px;
}

.plan-card__name {
    display: inline;
    margin: 0;
    font-size: 1.35rem;
}

.plan-card__tagline {
    color: var(--color-text-muted);
    font-size: 0.95rem;
}

.plan-card__heading {
    margin: var(--space-md) 0 var(--space-xs);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.plan-card__list,
.tier__list {
    list-style: none;
    display: grid;
    gap: var(--space-2xs);
    font-size: 0.95rem;
}

.plan-card__list li,
.tier__list li {
    padding-left: 1.1em;
    position: relative;
}

.plan-card__list li::before,
.tier__list li::before {
    content: "·";
    position: absolute;
    left: 0.25em;
    color: var(--color-marine-blue);
    font-weight: 700;
}

.plan-card__list--excluded li::before {
    content: "×";
    color: var(--color-text-muted);
    font-size: 0.9em;
}

.plan-card__cta {
    margin-top: auto;
    /* Pushed to the card foot so the CTA lines up across cards of different heights. */
    align-self: flex-start;
}

.plan-card__extras,
.plan-card__excluded { margin-bottom: var(--space-sm); }

.tier {
    border-top: 1px solid var(--color-border);
    padding: var(--space-xs) 0;
}

.tier__summary {
    cursor: pointer;
    padding: var(--space-xs) 0;
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 600;
}

.tier__list { margin: var(--space-xs) 0 var(--space-sm); }

.one-off {
    padding: var(--space-lg);
    border-radius: var(--radius);
    background: var(--color-off-white);
}

.one-off__prices {
    list-style: none;
    display: grid;
    gap: var(--space-xs);
    margin: var(--space-md) 0;
    max-width: 26rem;
}

.one-off__prices li {
    display: flex;
    justify-content: space-between;
    gap: var(--space-md);
    padding-bottom: var(--space-2xs);
    border-bottom: 1px solid var(--color-border);
}

.one-off__price {
    font-family: var(--font-heading);
    font-weight: 700;
    white-space: nowrap;
}

.one-off__offer {
    margin: var(--space-md) 0;
    padding: var(--space-md);
    border-left: 3px solid var(--color-sand);
    background: var(--color-white);
}

.one-off__terms {
    margin: 0;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* --- Legal pages ---------------------------------------------------------- */

/*
    A measure narrow enough to read a long document in. These pages are read carefully or
    not at all, so they get prose width rather than the wider marketing layout.
*/
.legal {
    max-width: 44rem;
    margin-bottom: var(--space-2xl);
}

.legal__updated {
    margin-bottom: var(--space-md);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.legal__intro {
    font-size: 1.05rem;
    margin-bottom: var(--space-lg);
}

.legal__section { margin-bottom: var(--space-lg); }

.legal__heading {
    font-size: 1.15rem;
    margin-bottom: var(--space-sm);
}

.legal__list {
    margin: 0 0 var(--space-md);
    padding-left: var(--space-md);
}

.legal__list li { margin-bottom: var(--space-2xs); }

/* Identification block: label above value, so a long address is not squeezed into a column. */
.legal__identity {
    margin: 0;
    padding: var(--space-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-off-white);
}

.legal__identity dt {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.legal__identity dd {
    margin: 0 0 var(--space-sm);
}

.legal__identity dd:last-child { margin-bottom: 0; }

/* Replaced by the shared .table-scroll utility above. */

.legal__table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.legal__table th,
.legal__table td {
    padding: var(--space-xs) var(--space-sm);
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border);
}

.legal__table thead th {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.legal__table tbody th {
    font-weight: 400;
    white-space: nowrap;
}

/* --- Not found (404) ------------------------------------------------------ */

.not-found__heading {
    font-size: 1.1rem;
    margin-bottom: var(--space-sm);
}

.not-found__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-md);
    margin: 0 0 var(--space-2xl);
    padding: 0;
    list-style: none;
}

.not-found__list a {
    display: inline-block;
    padding: var(--space-xs) 0;
}

/* --- Footer --------------------------------------------------------------- */

.site-footer {
    background: var(--color-navy);
    color: var(--color-off-white);
}

/*
    Inline footer links measured 16-19px tall, which leans on WCAG 2.2's spacing exception
    rather than clearing the 24px target minimum outright. inline-block makes the padding
    count towards the hit area, so they clear it on their own — and it is a real improvement
    on a phone, where the footer is a column of small links under a thumb.
*/
.site-footer a {
    display: inline-block;
    padding-block: 0.2rem;
}

.site-footer a {
    color: var(--color-off-white);
    text-decoration: none;
}

.site-footer a:hover {
    color: var(--color-sand);
    text-decoration: underline;
}

.site-footer__inner {
    display: grid;
    gap: var(--space-lg);
    max-width: var(--content-max);
    margin: 0 auto;
    padding: var(--space-xl) var(--space-md);
}

.site-footer__block--brand { max-width: 34rem; }

.site-footer__claim {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    color: var(--color-sand);
    margin: var(--space-sm) 0 var(--space-xs);
}

.site-footer__text {
    color: var(--color-off-white);
    opacity: 0.85;
    font-size: 0.95rem;
}

.site-footer__heading {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-sand);
    margin: 0 0 var(--space-sm);
}

.site-footer__list {
    list-style: none;
    display: grid;
    gap: var(--space-xs);
    font-size: 0.95rem;
}

.site-footer__legal {
    border-top: 1px solid rgba(245, 243, 238, 0.15);
}

.site-footer__legal,
.site-footer__legal-links {
    max-width: var(--content-max);
    margin: 0 auto;
}

.site-footer__legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-lg);
    padding: var(--space-md);
    font-size: 0.85rem;
}

.site-footer__provider {
    margin: 0;
    opacity: 0.8;
}

.site-footer__legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    list-style: none;
    margin: 0;
}

/* --- Wider screens -------------------------------------------------------- */

@media (min-width: 56rem) {
    :root { --header-height: 4.5rem; }

    .nav-toggle { display: none; }

    .site-header__inner { gap: var(--space-md); }

    /* Brief's desktop order: logo · nav · language selector · WhatsApp · Solicitar propuesta.
       The two actions join at 64rem below, once there is room for them on one row. */
    .site-header__collapse { order: 2; flex: 1; }
    .site-header__actions { order: 3; }

    /* The rule above it is a divider inside the open phone menu; on a row it would be a
       stray line beside the nav. */
    .site-header__collapse .lang--header {
        margin-top: 0;
        padding-top: 0;
        border-top: 0;
    }

    .site-header__collapse {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-lg);
    }

    .site-nav__list {
        flex-direction: row;
        align-items: center;
        gap: var(--space-md);
        margin: 0;
    }

    .site-nav__link { padding: var(--space-xs) 0; }

    /* "Boat Care Pläne Leistungen So funktioniert es" reads as one run of words at this gap.
       Divided like the language codes, and for the same reasons. Row layout only. */
    .site-nav__item + .site-nav__item { position: relative; }

    .site-nav__item + .site-nav__item::before {
        content: "";
        position: absolute;
        left: calc(var(--space-sm) / -2);
        top: 50%;
        transform: translateY(-50%);
        width: 1px;
        height: 0.9em;
        background: currentColor;
        opacity: 0.4;
    }

    /*
        Between the nav breakpoint and roughly 1150px, five regions on one row is a squeeze.
        Measured: adding the WhatsApp button (it only renders once a number is configured)
        pushed the actions onto a second row and took the header from one line to two at
        1100px and below, which is where a great deal of laptop traffic sits.

        Tightening the gaps and the header buttons buys back the room, rather than dropping a
        conversion path at exactly those widths. It never loosens again — see below for why.
    */
    .site-header__inner { gap: var(--space-sm); }
    .site-nav__list { gap: var(--space-sm); }
    .site-header__actions .btn { padding-left: var(--space-sm); padding-right: var(--space-sm); }

    .plans { grid-template-columns: repeat(3, 1fr); }

    .cols--3 { grid-template-columns: repeat(3, 1fr); }

    .contact { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }

    .report-block { grid-template-columns: minmax(0, 34rem) minmax(0, 1fr); }

    .site-footer__inner {
        grid-template-columns: 2fr 1fr 1fr 1fr auto;
    }

    .site-footer__block--brand { grid-row: span 1; }
}

/* --- Header actions move up from the action bar --------------------------- */

/*
    The nav unfolds at 56rem, but the header cannot hold logo, nav, language selector AND
    both calls to action until the content column reaches its 72rem cap — measured, not
    guessed. This said 64rem once; at 1024px every language still wrapped onto a second row
    and the header grew from 72px to 97px, because the column there is only 1009px wide.

    So the handover happens here rather than at the nav breakpoint. Between 56rem and 64rem
    the full nav is showing while the bottom action bar is still carrying WhatsApp and
    "Solicitar propuesta", which means no width loses a conversion path — the alternative
    was a band of tablet and small-laptop sizes with a two-line header, or with WhatsApp
    reachable only from the footer.
*/
@media (min-width: 72rem) {
    .site-header__actions { display: flex; }

    /* The bar is a phone and small-tablet affordance; from here the header carries the same
       two actions, so showing both would duplicate them. */
    .action-bar { display: none; }

    body { padding-bottom: 0; }
}

/* A 75rem block here once restored the roomier gaps the 56rem rules tighten. It was wrong:
   --content-max caps the header at 72rem, so past 1152px the viewport grows and the row does
   not. German needs 1133px of that 1152 tightened, 1183 loosened — which is why it wrapped at
   1280 and 1440 while fitting at 1150. Do not restore it. */

/* =============================================================================
   Redesign (client mockup, September 2026)
   -----------------------------------------------------------------------------
   The same content and the same approved copy, presented the way the client's
   mockup shows it: dark full-bleed bands, small-caps eyebrows over each heading,
   sand as the call-to-action colour on dark ground, and numbered process cards.

   Sand is the accent the brief reserves, so it earns the primary button only on
   the navy bands, where it is the one warm thing on a cold field. On white ground
   the primary button stays marine blue, and sand never becomes dominant.
   ============================================================================= */

/* --- Eyebrow labels ------------------------------------------------------- */

.eyebrow {
    display: block;
    margin-bottom: var(--space-xs);
    font-family: var(--font-heading);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-marine-blue);
}

.band-dark .eyebrow { color: var(--color-sand); }

/* --- Dark bands ----------------------------------------------------------- */

.band-dark {
    position: relative;
    padding: var(--space-2xl) 0;
    background: var(--color-navy);
    color: var(--color-off-white);
    overflow: hidden;
}

.band-dark h1,
.band-dark h2,
.band-dark h3 { color: var(--color-off-white); }

.band-dark p { color: rgba(245, 243, 238, 0.82); }

/* The hero fades from navy into the marine blue, which is what puts the Boat
   Report card on a lighter ground at the foot of the section. */
.band-dark--gradient {
    background: linear-gradient(170deg, var(--color-navy) 0%, var(--color-navy) 42%, #16455C 100%);
}

/* Two very faint arcs, echoing the rays in the mark without repeating it.
   Decorative and behind everything, so they never intercept a click. */
.band-dark--arcs::before,
.band-dark--arcs::after {
    content: "";
    position: absolute;
    border: 1px solid rgba(213, 197, 163, 0.18);
    border-radius: 50%;
    pointer-events: none;
}

.band-dark--arcs::before {
    width: 46rem;
    height: 46rem;
    right: -14rem;
    top: -10rem;
}

.band-dark--arcs::after {
    width: 30rem;
    height: 30rem;
    right: 4rem;
    bottom: -18rem;
}

/* --- Buttons on dark ------------------------------------------------------ */

.btn--sand {
    background: var(--color-sand);
    color: var(--color-navy);
}

.btn--sand:hover { background: #C4B48F; }

.btn--outline {
    background: transparent;
    color: var(--color-off-white);
    border-color: rgba(245, 243, 238, 0.55);
}

.btn--outline:hover {
    background: rgba(245, 243, 238, 0.10);
    border-color: var(--color-off-white);
}

/* --- Hero ----------------------------------------------------------------- */

/* No max-width. It was 44rem, which is right on the home page — the Boat Report card takes
   the other half of that band — and wrong everywhere else, where nothing does: it left 448px
   of empty navy to the right of every H1 and wrapped "Todo lo necesario para mantener el
   control" onto two lines with room to spare, reading as a missing image.

   Home keeps its measure from .hero-split's grid column instead, and .hero__intro carries
   its own cap so the paragraph stays readable while the heading uses the band. */
.hero--dark {
    position: relative;
    z-index: 1;
    margin-bottom: 0;
}

.hero--dark h1 { margin-bottom: var(--space-md); }

.hero--dark .hero__intro { color: rgba(245, 243, 238, 0.86); }

.hero--dark .hero__microcopy { color: rgba(245, 243, 238, 0.70); }

/* --- Trust grid ----------------------------------------------------------- */

/* Four claims as a 2x2 of quiet boxes, each a headline with the detail under it. */
.trust-grid {
    display: grid;
    gap: 1px;
    margin: 0 0 var(--space-2xl);
    padding: 0;
    list-style: none;
    background: var(--color-border);
    border-block: 1px solid var(--color-border);
}

.trust-grid li {
    padding: var(--space-lg) var(--space-md);
    background: var(--color-off-white);
    text-align: center;
}

.trust-grid__title {
    display: block;
    font-family: var(--font-heading);
    font-weight: 600;
    margin-bottom: var(--space-2xs);
}

.trust-grid__detail {
    display: block;
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

/* --- Numbered process ----------------------------------------------------- */

.process-grid {
    display: grid;
    gap: var(--space-lg);
    margin: var(--space-lg) 0 0;
    padding: 0;
    list-style: none;
    counter-reset: process;
}

.process-grid li {
    counter-increment: process;
    padding-top: var(--space-md);
    border-top: 2px solid var(--color-navy);
}

/* The number is generated, so the step order lives in the markup rather than in
   the copy — the same reasoning as the ordered list it replaces. */
.process-grid li::before {
    content: "0" counter(process);
    display: block;
    margin-bottom: var(--space-xs);
    font-family: var(--font-heading);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-sand);
}

.process-grid__title {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    font-weight: 700;
    margin: 0 0 var(--space-2xs);
}

.process-grid p {
    margin: 0;
    font-size: 0.95rem;
    color: var(--color-text-muted);
}

/* --- Price display -------------------------------------------------------- */

/* The number carries the weight; the unit stays deliberately quiet beside it. */
.price {
    display: flex;
    align-items: baseline;
    gap: 0.4ch;
    font-family: var(--font-heading);
    margin: 0 0 var(--space-sm);
}

.price__amount {
    font-size: 2.1rem;
    font-weight: 800;
    line-height: 1;
}

.price__unit {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

.band-dark .price { justify-content: center; }
.band-dark .price__amount { color: var(--color-off-white); }
.band-dark .price__unit { color: rgba(245, 243, 238, 0.70); }

/* --- One-off check band --------------------------------------------------- */

/* A single offer panel, centred as one block. It used to be left-aligned copy with a
   centred price and button underneath, which read as two decisions rather than one. */
.oneoff__inner {
    max-width: 42rem;
    margin-inline: auto;
    text-align: center;
}

.oneoff__rule {
    margin: var(--space-lg) 0;
    border: 0;
    border-top: 1px solid rgba(245, 243, 238, 0.25);
}

.oneoff__price { text-align: center; margin-bottom: var(--space-lg); }

.oneoff__bracket {
    display: block;
    margin-top: var(--space-2xs);
    font-size: 0.85rem;
    color: rgba(245, 243, 238, 0.70);
}

.oneoff__cta { text-align: center; }

/* --- Length-bracket toggle ------------------------------------------------ */

/* Progressive enhancement, and the reason it is built this way: every bracket's
   price is rendered server-side and visible. site.js turns the list into a
   segmented control and hides the inactive one. With no script every price is
   simply on the page — which keeps the rule that prices are never gated behind
   JavaScript literally rather than nearly. */
.bracket-toggle {
    display: inline-flex;
    margin-bottom: var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-white);
}

.bracket-toggle button {
    padding: var(--space-xs) var(--space-md);
    min-height: 2.75rem;
    border: 0;
    background: transparent;
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
}

.bracket-toggle button[aria-pressed="true"] {
    background: var(--color-navy);
    color: var(--color-off-white);
}

/* --- Plan cards ----------------------------------------------------------- */

.plan-card--flag { position: relative; }

/* The badge as a tab in the corner, the way the mockup shows it. */
.plan-card__flag {
    position: absolute;
    top: -1px;
    right: -1px;
    padding: var(--space-2xs) var(--space-sm);
    background: var(--color-marine-blue);
    color: var(--color-white);
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border-bottom-left-radius: var(--radius);
}

@media (min-width: 40rem) {
    .trust-grid { grid-template-columns: 1fr 1fr; }
    .process-grid { grid-template-columns: 1fr 1fr; column-gap: var(--space-xl); }
}

/* --- Tinted band ---------------------------------------------------------- */

/* The off-white ground the mockup puts behind the plans, so they read as a set
   rather than as three more cards on the page. */
.band-tint {
    padding: var(--space-2xl) 0;
    background: var(--color-off-white);
}

/* A section that supplies its own band padding does not need its own margin too. */
.section--flush { margin-bottom: 0; }

/* --- Boat Report inside the hero ------------------------------------------ */

/* The sample report sits on the lighter end of the hero gradient: the claim above
   it, the evidence for the claim below. On a phone it simply follows the copy. */
.report-block--hero {
    position: relative;
    z-index: 1;
    display: block;
    max-width: 34rem;
    margin-top: var(--space-2xl);
}

.report-block--hero .report {
    background: var(--color-white);
    color: var(--color-text);
    border-radius: var(--radius);
    box-shadow: 0 18px 40px rgba(11, 31, 51, 0.28);
}

/* The card is white, so the band-dark text colours must not leak into it. */
.report-block--hero .report h2,
.report-block--hero .report h3,
.report-block--hero .report p,
.report-block--hero .report td,
.report-block--hero .report th { color: var(--color-text); }

/* The legend keeps its own block lower down the page. */
.report-block--legend { display: block; }

/* The card is never wider than 32rem here, so the rules written for the full-measure
   version it has on Boat Care work against it: the two-column meta wraps "Jeanneau Cap
   Camarat 7.5" over three lines, and a 10rem label column leaves the values too narrow to
   sit on one. Between them they made the card twice the height of the copy beside it.

   Compacted, not shortened: every field the brief specifies is still on the card. */
.report-block--hero .report { padding: var(--space-md); }

.report-block--hero .report__meta {
    grid-template-columns: 1fr;
    gap: var(--space-2xs);
    margin: var(--space-sm) 0;
}

.report-block--hero .report__meta dt { min-width: 6rem; }
.report-block--hero .report__line { padding: var(--space-2xs) 0; font-size: 0.9rem; }
.report-block--hero .report__lines { margin-bottom: var(--space-sm); }
.report-block--hero .report__recommendation { padding: var(--space-sm) var(--space-md); }

/* --- The home hero, split ------------------------------------------------- */

/* The claim on one side, the evidence for it on the other. Stacked below 70rem, and in
   that order deliberately: the report card means nothing to somebody who has not read
   the claim yet, so the copy comes first on a phone.

   The report column is capped rather than fixed. A 34rem card next to a text column that
   has been squeezed under about 26rem reads as a card with a caption beside it, not as
   two columns, which is why the split waits for the room instead of arriving with it. */
.hero-split { display: grid; gap: var(--space-xl); }

@media (min-width: 70rem) {
    .hero-split {
        grid-template-columns: minmax(0, 1fr) minmax(0, 32rem);
        gap: var(--space-2xl);
        align-items: center;
    }

    /* The band supplies the space now that the card is beside the copy rather than under it. */
    .hero-split .report-block--hero { margin-top: 0; }

    /* The copy has less to say than the card has to show, so it takes its half of the band
       as air rather than leaving the card looking like the only thing on it. */
    .hero-split .hero__intro { font-size: 1.2rem; }
    .hero-split .hero__actions { margin-top: var(--space-xl); }
}

/* --- Per-bracket pricing in a plan card ----------------------------------- */

.plan-card__pricing { margin-bottom: var(--space-sm); }

.price__bracket {
    display: block;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.price__amount--quote {
    font-size: 1.4rem;
    font-weight: 700;
}

/* Once the toggle is running it names the length itself, so repeating it under
   every price would say the same thing twice. Without script the class is never
   added and the labels stay, which is the whole point of them. */
.brackets-enhanced .price__bracket { display: none; }

/* --- Frequency tiers as labelled sections --------------------------------- */

/* The mockup shows these as small-caps labels over their content rather than as
   obvious accordions. They stay <details>, so they are still keyboard accessible
   with no script and their content is still in the DOM for crawlers; site.js
   opens them on wide screens. Only the marker and the label change. */
.tier__summary {
    font-family: var(--font-heading);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-marine-blue);
}

.tier__summary::marker { color: var(--color-sand); }

/* --- The redesign frame on the interior pages ----------------------------- */

/* Every page now opens with the navy band, which supplies its own padding — but the old
   white hero left space behind it that the page after it still needs. Listed by the
   elements that actually follow a band rather than as `.band-dark + *`, because on the home
   page what follows is the trust strip, and that one is meant to butt right up against it. */
.band-dark + .section,
.band-dark + .services,
.band-dark + .faq,
.band-dark + .contact,
.band-dark + .notice,
.band-dark + .bracket-toggle,
.band-tint + .section { margin-top: var(--space-2xl); }

/* The plans page puts the length selector directly under the band, and site.js is what
   reveals it. With no script it stays hidden and therefore takes up no space, so the
   section after it is the one that needs the gap instead. */
.band-dark + .bracket-toggle[hidden] + .plans { margin-top: var(--space-2xl); }

/* A band supplies the space around whatever it wraps, so the thing inside should not add
   its own bottom margin on top of it. */
.band-tint .report,
.band-tint .trust-grid { margin-bottom: 0; }

/* The cells are off-white, which is the band's own ground — left alone only the hairlines
   between them showed. White makes them read as tiles again. */
.band-tint .trust-grid li { background: var(--color-white); }

/* --- Tiles ---------------------------------------------------------------- */

/* Short claims as quiet cards rather than bullets: the treatment the mockup gives a list
   where every item is one line and none outranks the others. The marine-blue top edge is
   the same device the numbered process cards use, so the two read as one family. */
.tile-grid {
    display: grid;
    gap: var(--space-md);
    margin: var(--space-lg) 0 0;
    padding: 0;
    list-style: none;
}

/* Stepped rather than auto-fit: five tiles across four columns leaves one stranded on a
   row of its own, and three columns reads as 3 + 2. */
@media (min-width: 40rem) { .tile-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 60rem) { .tile-grid { grid-template-columns: repeat(3, 1fr); } }

.tile-grid li {
    padding: var(--space-md);
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-marine-blue);
    border-radius: var(--radius);
    font-size: 0.95rem;
}

/* --- Services as a catalogue ---------------------------------------------- */

/* Two columns once there is room for them. The cards carry their own max-width for the
   single-column case, which has to come off inside a grid track or the second column sits
   in a half-empty cell. */
@media (min-width: 56rem) {
    .services { grid-template-columns: 1fr 1fr; }
    .services .service { max-width: none; }
}

/* The coordination callout marks itself out by sitting on a different ground from the page
   around it. Inside a tinted band that ground is already off-white, so it takes white
   instead — otherwise the one line that keeps the offer honest stops looking like a callout
   at all. */
.band-tint .service__important { background: var(--color-white); }
