/* LEDO editorial presentation. Brand colours and type remain defined in ledo.css. */
/* TWO EDGES, NOT ONE (Owner, 2026-09-18: the text sits hard against the left
   edge of the gradient).

   `--gutter` is where the DESIGN ends: the rules between blocks and the panels'
   own backgrounds are drawn on it. `--text-inset` is the little more that the
   WORDS keep, so a paragraph never touches the edge of the panel it sits in.
   It is stated once and added by every container, so the whole site moves
   together and the grid holds; change it here and nothing else. */
:root { --page-width: 92rem; --gutter: clamp(1.25rem, 3.5vw, 3rem); --text-inset: 5px; }
body { -webkit-font-smoothing: antialiased; }
::selection { background: var(--blue-bright); color: var(--night); }
:where(a, button):focus-visible { outline: 2px solid var(--blue-bright); outline-offset: 5px; }
:where(section[id]) { scroll-margin-top: 1.5rem; }
.site-header { max-width: var(--page-width); display: grid; grid-template-columns: auto 1fr auto auto; gap: 1.6rem; padding: 1.15rem calc(var(--gutter) + var(--text-inset)); border-bottom: 1px solid var(--line); }
.brand { gap: .6rem; font-size: .8rem; letter-spacing: .19em; white-space: nowrap; }
/* A soft shadow that follows the emblem's own outline (Owner, 2026-09-19):
   the cut-out edge of the PNG is a little rough, and a shadow cast from the
   alpha rather than the box blurs that edge and lifts the badge off the
   header. Two passes: a tight dark one that swallows the fringe, and a soft
   wider one that is the actual shadow. */
.brand-logo { width: 5.6rem; height: 5.6rem; filter: drop-shadow(0 0 2px rgb(0 0 0 / 85%)) drop-shadow(0 .5rem 1.1rem rgb(0 0 0 / 70%)); }
/* DESKTOP CARRIES IT LARGER (Owner, 2026-09-16, twice again). Only above the
   burger's breakpoint: on a phone the header is brand, burger and language in
   one row, and a 180px badge would leave room for nothing else. */
@media (min-width: 1101px) {
    /* THE ROW MUST FIT THE WINDOW (Owner, 2026-09-19: "on many sizes the site
       is cut off on the right"). Measured logged out at 1101px the header's
       content was 1214px: a 179px emblem, a 304px booking button, four links
       and the language pill, none of them allowed to give. Logged in, the
       account links add 150px more, and the overflow ran to about 1400px.
       So between 1101 and 1400 the emblem, the button, the wordmark and the
       gaps scale with the window - each reaching the size the Owner approved
       at 1400 and standing there from then on. The button is capped with
       max-width because nav-booking.css loads later and sets its width. */
    .brand-logo { width: clamp(7rem, 12.8vw, 11.2rem); height: clamp(7rem, 12.8vw, 11.2rem); }
    .site-header { gap: clamp(.9rem, 1.8vw, 1.6rem); }
    .site-header > nav { min-width: 0; }
    /* THE MENU LINKS ON A DESKTOP (Owner, 2026-09-19): two steps larger, in
       capitals, and under the cursor a white bar - three times a hairline -
       drawn from the link's left edge to its middle, 10px above the text.
       The bar grows from the left, so the eye reads it as a stroke and not
       as a switch. */
    .site-header > nav .nav-links a {
        position: relative;
        /* 14.4px from 1400 up, easing to 12.8 at 1101, so the row that holds
           the Russian capitals at 1400 also holds them at the narrow end. */
        font-size: clamp(.8rem, 1.03vw, .9rem);
        letter-spacing: .1em;
        text-transform: uppercase;
    }
    .site-header > nav .nav-links a::before {
        content: "";
        position: absolute;
        left: 0;
        top: -13px;
        width: 0;
        height: 3px;
        background: #fff;
        transition: width .22s ease;
    }
    .site-header > nav .nav-links a:hover::before,
    .site-header > nav .nav-links a:focus-visible::before { width: 50%; }
    @media (prefers-reduced-motion: reduce) { .site-header > nav .nav-links a::before { transition: none; } }
    /* The account links (Mine reiser / Logg ut, Logg inn / Registrer deg) are
       a sibling of <nav>, not a child of it (see base.html), so the rule
       above never reached them - the client's word for it (2026-09-20): "not
       all the words at the top became capitals". Same size, same tracking,
       same underline; .header-account carries no href of its own to collide
       with the bar's :hover. */
    .header-account a, .nav-account-form button {
        position: relative;
        font-size: clamp(.8rem, 1.03vw, .9rem);
        letter-spacing: .1em;
        text-transform: uppercase;
    }
    .header-account a::before, .nav-account-form button::before {
        content: "";
        position: absolute;
        left: 0;
        top: -13px;
        width: 0;
        height: 3px;
        background: #fff;
        transition: width .22s ease;
    }
    .header-account a:hover::before, .header-account a:focus-visible::before,
    .nav-account-form button:hover::before, .nav-account-form button:focus-visible::before { width: 50%; }
    @media (prefers-reduced-motion: reduce) {
        .header-account a::before, .nav-account-form button::before { transition: none; }
    }
    /* THE WORDMARK DOES NOT FIT THE DESKTOP ROW, at any width. The page is
       capped at --page-width, so past 1400px the header gains nothing; and in
       that row the Russian capitals, the button, the account links and the
       language pill leave 70 to 150px less than the wordmark needs. Measured
       logged in, in Russian, at 1101, 1300, 1400, 1500 and 1600. The emblem
       carries the name itself, so the wordmark stands down here; it is still
       read out to assistive technology through the brand link's aria-label. */
    .brand span { display: none; }
    .site-header > nav { gap: .9rem; }
    /* The narrow end of the desktop, in Russian capitals: at 1101px the nav's
       column is 603px and its content 662. The button comes down to 13rem,
       the links close up and their tracking eases, which is the 60px. */
    @media (max-width: 1250px) {
        .site-header > nav { gap: .6rem; }
        .site-header .nav-cta-art { max-width: 12rem; }
        .site-header > nav .nav-links a, .header-account a, .nav-account-form button { letter-spacing: .06em; }
    }
    .site-header .nav-cta-art { max-width: clamp(13rem, 21.7vw, 19rem); }
    /* NO LANGUAGE SLIDES UNDER THE BADGE (Owner, Carpet #848). The rules above
       were sized for Russian; Lithuanian and Spanish words are longer, and the
       row ran left under the emblem from 1101 to about 1440px. The tracking
       now eases from .02em at 1101 to the full .1em by 1341, which keeps
       English, Chinese and most of the range on one row; where a language
       still does not fit, the menu wraps onto a second line inside its own
       column, above the booking button, instead of under the logo. */
    .site-header > nav { flex-wrap: wrap; justify-content: flex-end; row-gap: .45rem; }
    .site-header > nav .nav-links a, .header-account a, .nav-account-form button {
        letter-spacing: clamp(.02em, calc((100vw - 1101px) / 3000), .1em);
    }
    /* THE WORDMARK IS PART OF THE LOCKUP, not a caption under a picture. Beside
       a 180px badge, 13px of tracked capitals read as a stray line of text: the
       eye wants the type at roughly a fifth of the mark, so 23px with the
       tracking eased back - wide tracking at that size starts to pull the two
       words apart - and the gap between them a little wider than the letters'
       own, so the badge and the name read as one object. */
    .brand { gap: clamp(.7rem, 1.3vw, 1.15rem); font-size: clamp(1rem, 1.66vw, 1.45rem); letter-spacing: .13em; }
    .brand span { line-height: 1.1; }
}
.site-header > nav { justify-content: flex-end; gap: clamp(.85rem, 1.5vw, 1.65rem); }
.site-header > nav a, .nav-account-form button { font-size: .75rem; white-space: nowrap; }
/* The account links moved out of <nav> so a phone can put them in the top
   row; they keep the nav's typography and spacing. */
.header-account { display: inline-flex; align-items: center; gap: clamp(.85rem, 1.5vw, 1.65rem); }
/* Account links sit outside <nav>, so the sitewide `nav a { text-decoration:
   none }` never reached them - the browser's own underline was showing under
   "Logg inn" the whole time, just easy to miss in lower case (2026-09-20:
   the caps rule above made it obvious). Own underline is the hover bar. */
.header-account a, .header-account button { font-size: .75rem; white-space: nowrap; text-decoration: none; }
.nav-cta { padding: .65rem .9rem; border-radius: .35rem; }
.nav-account-form button { min-height: 2.5rem; }
/* The burger. Above 1100px the links are display:contents, so the header lays
   out exactly as it did before the wrapper existed and this button is gone. */
.site-header { position: relative; }
.nav-links { display: contents; }
.header-right { display: contents; }
/* KRONER OR EURO (Owner and Violeta, 2026-09-26): kroner by default, one
   switch beside the language picker shows euro instead. Every price is
   written in both; <html data-currency> decides which is seen (currency.js). */
html:not([data-currency="eur"]) [data-cur="eur"], html[data-currency="eur"] [data-cur="nok"] { display: none; }
.header-prefs { display: flex; align-items: center; gap: .45rem; }
.currency-switch { display: inline-flex; align-items: center; min-height: 2.25rem; padding: 2px; border: 1px solid #2b3c53; border-radius: 999px; background: rgb(18 31 48 / 48%); }
.currency-switch button { min-height: calc(2.25rem - 6px); padding: 0 .6rem; border: 0; border-radius: 999px; background: transparent; color: #8fa1b6; font: inherit; font-size: .72rem; font-weight: 650; letter-spacing: .04em; cursor: pointer; }
.currency-switch button[aria-pressed="true"] { background: #12304b; color: var(--ice); box-shadow: inset 0 0 0 1px rgb(128 193 255 / 48%); }
.currency-switch button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
/* The copy beside "Price" in the burger is the phone's; see the 620px block.
   Elsewhere its row is display:contents, so "Price" is an ordinary nav link. */
.nav-price-row { display: contents; }
.currency-switch--burger { display: none; }
.nav-toggle { display: none; align-items: center; justify-content: center; width: 2.6rem; height: 2.6rem; padding: 0; border: 1px solid color-mix(in srgb, var(--blue-bright) 42%, transparent); border-radius: .38rem; background: linear-gradient(135deg, rgb(22 48 75 / 88%), rgb(8 15 25 / 86%)); cursor: pointer; }
.nav-toggle span { position: relative; display: block; width: 1.1rem; height: 1px; background: var(--ice); }
.nav-toggle span::before, .nav-toggle span::after { position: absolute; left: 0; width: 100%; height: 1px; content: ""; background: var(--ice); }
.nav-toggle span::before { top: -.35rem; }
.nav-toggle span::after { top: .35rem; }
/* Less air over the first line on the page (Owner, 2026-09-16). */
.hero { isolation: isolate; min-height: 41rem; max-width: var(--page-width); grid-template-columns: 1.2fr .8fr; gap: 2rem; margin: 0 auto; padding: 2.5rem calc(var(--gutter) + var(--text-inset)) 2.25rem; overflow: hidden; }
.hero-landscape { position: absolute; z-index: -3; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 68% center; }
.hero::before { z-index: -2; inset: 0; width: auto; height: auto; border-radius: 0; background: linear-gradient(90deg, var(--night) 2%, rgb(7 11 18 / 92%) 25%, rgb(7 11 18 / 18%) 80%), linear-gradient(0deg, var(--night), transparent 38%); }
.hero::after { content: ""; position: absolute; z-index: -1; inset: 0; background: linear-gradient(180deg, rgb(7 11 18 / 22%), transparent 45%); pointer-events: none; }
/* THE FIRST LINE IS A LINE (Owner, 2026-09-16). The <br> in the markup says
   where the heading breaks; a 14ch cap broke it again somewhere else, so
   "Частный трансфер" arrived as "Частный / трансфер" and the second line
   became the third. The cap is gone - the break is the markup's job. */
.hero h1 { overflow-wrap: anywhere; }
.hero .eyebrow { margin-bottom: 1.65rem; }
.eyebrow { font-size: .65rem; letter-spacing: .2em; }
.eyebrow span { flex-shrink: 0; width: 1.7rem; }
.hero-lead { max-width: 33rem; margin: 1.7rem 0; font-size: 1rem; line-height: 1.8; color: var(--ice); }
.hero-note { max-width: 30rem; margin: 1.1rem 0 0; color: var(--muted); font-size: .72rem; line-height: 1.6; }
.button { min-height: 3.2rem; gap: 1.65rem; padding: .85rem 1.25rem; border-radius: .4rem; font-size: .85rem; font-weight: 600; transition: background .2s, border-color .2s, transform .2s, box-shadow .2s; }
.button-primary { box-shadow: 0 5px 22px color-mix(in srgb, var(--blue) 12%, transparent); }
.button-primary:hover { box-shadow: 0 8px 28px color-mix(in srgb, var(--blue) 24%, transparent); }
.button-quiet { background: rgb(7 11 18 / 32%); }

.button-quiet:hover { border-color: var(--blue-bright); }
.hero-visual { min-height: 25rem; height: 100%; display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; padding-top: 1rem; }
.hero-visual::before, .hero-visual::after { content: none; }
.hero-signature { order: -1; display: grid; text-align: right; line-height: .88; letter-spacing: -.07em; font-size: clamp(3rem, 6vw, 6.5rem); font-weight: 700; color: rgb(220 238 255 / 72%); }
.hero-signature b { margin-top: .7rem; font-weight: 400; font-size: .7rem; letter-spacing: .65em; }
.hero-visual .route-card { position: relative; bottom: auto; width: 100%; max-width: 23rem; transform: none; padding: 1.5rem; border-color: rgb(220 238 255 / 22%); border-radius: .5rem; background: rgb(7 11 18 / 60%); box-shadow: 0 16px 50px rgb(0 0 0 / 15%); }
.route-line { margin-bottom: 1rem; }
.route-line i { width: .5rem; height: .5rem; box-shadow: none; }
/* THE TWO CITIES SIT SIDE BY SIDE WHILE THERE IS ROOM, and drop under one
   another when there is not (Owner, 2026-09-23 pointed at the card between
   621 and 900px, where they were stacked by a rule of their own while the
   card was wide enough to hold both). Wrapping decides it by measurement, so
   there is no width at which the card reads as broken. */
.route-cities { flex-wrap: wrap; gap: .75rem; font-size: .85rem; }
.route-card p { margin: 1rem 0 0; padding-top: .8rem; border-top: 1px solid var(--line); font-size: .73rem; letter-spacing: .025em; text-align: center; }
.trust-strip { max-width: calc(var(--page-width) - 2 * var(--gutter)); margin-inline: auto; }
.trust-strip article { padding: 1.4rem 1.5rem; gap: .9rem; }
.trust-strip article > span { display: grid; place-items: center; width: 2rem; height: 2rem; flex-shrink: 0; border: 1px solid var(--line); border-radius: 50%; font-size: .65rem; }
.trust-strip strong { font-size: .84rem; font-weight: 600; }
.trust-strip small { font-size: .72rem; line-height: 1.5; }
/* LESS AIR UNDER A SECTION (Owner, 2026-09-16: the page is stretched by it).
   The bottom was 4.5rem and the next section adds 2rem of its own on top, so
   every seam was 104px of nothing. 2.25rem makes it 68. */
.section { max-width: var(--page-width); padding: 3rem calc(var(--gutter) + var(--text-inset)) 2.25rem; }
/* A consistent hairline marks each new content chapter. */
.section + .section { padding-top: 2rem; border-top: 1px solid var(--line); }

/* EVERY RULE BETWEEN BLOCKS STOPS WHERE THE CONTENT STOPS (Owner, 2026-09-18:
   the site is not fluid, the margins left and right are the design, and a line
   that runs past them reads as crooked).

   These rules are the border of the block itself, so they were drawn across the
   border box - the full width of the page - while the words inside sat one
   gutter in. The border stays where it is and is painted with a gradient that
   is transparent for exactly that gutter at each end, so the line begins and
   ends on the same axis as the text above it. Nothing is repositioned, no
   element gains a layer, and the ends follow `--gutter` when it changes with
   the viewport. */
.site-header,
.section + .section,
.fleet,
.trust-strip,
.booking-section,
.closing,
.site-footer {
    border-image: linear-gradient(to right,
        transparent 0 var(--gutter),
        var(--line) var(--gutter) calc(100% - var(--gutter)),
        transparent calc(100% - var(--gutter)) 100%) 1;
}
/* ONE RHYTHM BETWEEN BLOCKS. A block gives 4.5rem below and the next gives
   2rem above, so every seam is 6.5rem. The trust strip has no padding of its
   own, so the section after it carries the whole 6.5rem itself; measured on
   production the seams were 72/104/104/104/132/92/68px. Keep the pair adding
   up when you touch either half. */
.trust-strip + .section { padding-top: 3rem; }
.section h2, .closing h2 { text-wrap: balance; overflow-wrap: anywhere; }
/* The eyebrow is a <p> too, and this used to catch it; a second rule then
   put it back. Leaving the label out here means one rule governs its size. */
.section p:not(.eyebrow) { font-size: .9rem; }
/* ONE VERTICAL GUIDE DOWN THE RIGHT SIDE (Owner, 2026-09-16). Every section
   that has a right-hand block starts it on the same line: the price list, the
   fleet copy and the questions already used .8fr/1.2fr with a 3rem gap, which
   puts that edge 544px into the content box - measured at x=592 on a 1400px
   screen. These sections were 1fr/1fr (x=717) and the booking form .75/1.25
   (x=561), so three different edges ran down one page. */
.process, .beyond { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; align-items: start; }
.process .section-heading, .beyond .section-heading { max-width: none; }
.steps { grid-template-columns: 1fr; gap: 0; margin: 0; border: 0; background: none; }
/* A row of a panel, laid out exactly like a fare row: the same 1rem above and
   below, the same 8px corner that curls the ends of the rule under it, and no
   rule under the last one. Before this the steps had 1.5rem rows with the first
   and last flush against the frame, which is what made the panels look like
   three different designs. */
/* The rows paint NOTHING. ledo.css gives `.steps article` `background: var(--night)`
   from the days when each step was its own dark tile; inside a panel that black
   covers the surface everywhere except the panel's own padding, which is the
   dark band the Owner kept pointing at. */
.steps article { background: none; }
.steps article { min-height: 0; display: grid; grid-template-columns: 2rem 1fr; column-gap: 1.5rem; padding: 1rem 0; border-bottom: 1px solid var(--line); border-radius: .5rem; }
.steps article:first-child { padding-top: 1rem; }
/* The rule under the last step separated it from nothing and left a band of
   empty page under the list (Owner, 2026-09-16). */
.steps article:last-child { padding-bottom: 1rem; border-bottom: 0; }
.steps b { grid-row: 1 / 3; margin-top: .35rem; font-weight: 500; }
.steps h3 { margin: 0 0 .5rem; font-size: 1.12rem; }
.steps p { margin: 0; max-width: 35rem; font-size: .85rem; }
/* In the middle of the whole step, not of its text column (Owner, 2026-09-19). */
.steps .step-action { grid-column: 1 / -1; justify-self: center; margin-top: 1rem; }
.fleet { border-top: 1px solid var(--line); }
/* One block now: the eyebrow, the heading and the line that explains it, which
   used to sit in a second column across the page from what it was explaining. */
.fleet-header { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
.fleet-header .section-heading { max-width: none; }
.fleet-intro { max-width: 40rem; margin: .7rem 0 0; color: var(--muted); line-height: 1.7; }
.fleet > .fleet-intro:last-child { margin-top: 1rem; }
.fleet-grid { gap: 1.1rem; margin-block: 1.8rem 1rem; }
.fleet-card { position: relative; display: flex; flex-direction: column; padding: 1.6rem; border-radius: .55rem; overflow: hidden; background: linear-gradient(145deg, var(--panel), var(--night-soft)); transition: border-color .25s, transform .25s; }
.fleet-card::before { content: ""; width: 3rem; height: 2px; background: var(--blue-bright); position: absolute; top: 0; left: 1.6rem; }
.fleet-index { color: var(--muted); font-size: .65rem; letter-spacing: .16em; margin-bottom: 2.2rem; }
/* THE FLEET CARDS, after System.A's "today" card on its schedule page (Owner,
   2026-09-16). Same three ideas on all three cars - the card stands a little
   proud, carries its own border and wash, and has a firefly running the rim -
   in the colour of the class: green for Standard, blue for Premium, burgundy
   for Luxury.

   The treatment is written once and the colour is passed in, because three
   copies of a conic gradient differing only in their stops is three places to
   get it wrong. `--tier-core` is the bright head of the firefly, `--tier-mid`
   its body and the border, `--tier-deep` the tail.

   The rim rides `::after`: `::before` is the little bar every fleet card wears,
   and the card clips its overflow, so the ring sits just inside the edge
   instead of 2px outside it as on System.A. It reuses `--ledo-firefly` and its
   keyframes - the same light that runs round the notices and the booking
   button - rather than declaring a second one. */
/* Blue is what a card wears when nothing has said otherwise, so it is
   declared FIRST - a class further down the stylesheet wins, and a card
   that also carries a tier must come out in the tier's colour, not in this
   one (Owner, 2026-09-24: the order form on the green car's page). */
.tier-card { --tier-core: rgb(230 245 255); --tier-mid: rgb(85 167 255); --tier-deep: rgb(20 60 100); }
.fleet-card--standard, .vehicle-page--standard { --tier-core: rgb(222 248 232); --tier-mid: rgb(120 220 150); --tier-deep: rgb(28 78 52); }
/* THE SAME CARD AROUND EVERY ORDER FORM THAT HAS A PAGE OF ITS OWN (Owner,
   2026-09-19: "in the style of the blue car card"). `.tier-card` is the fleet
   treatment with a name a form can wear - the lift, the border, the wash, the
   bar, the firefly and the sheen - and with no class of its own it is blue,
   the Premium colour. The three class pages, the custom route and the contact
   page put it on. The front page's panel stays a panel: it is one block among
   many there, not the page's subject.
   Without the sheen: a band of light sweeping across a form you are typing
   into is not a treatment, it is a distraction (Owner, 2026-09-19). */
.tier-card { position: relative; overflow: hidden; border: 1px solid var(--line); }
.fleet-card--premium, .vehicle-page--premium { --tier-core: rgb(230 245 255); --tier-mid: rgb(85 167 255); --tier-deep: rgb(20 60 100); }
.fleet-card--luxury, .vehicle-page--luxury { --tier-core: rgb(255 217 217); --tier-mid: rgb(198 90 96); --tier-deep: rgb(90 25 32); }

.fleet-card--standard, .fleet-card--premium, .fleet-card--luxury, .tier-card {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--tier-mid) 45%, transparent);
    background-image: linear-gradient(135deg,
        color-mix(in srgb, var(--tier-mid) 16%, transparent),
        color-mix(in srgb, var(--tier-mid) 4%, transparent));
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 10%), 0 .9rem 2rem rgb(0 0 0 / 35%);
    transition: transform .25s, border-color .25s, box-shadow .25s;
}
.fleet-card--standard::before, .fleet-card--premium::before, .fleet-card--luxury::before, .tier-card::before {
    background: var(--tier-mid);
}
/* The bar the fleet card gets from `.fleet-card::before`; the form card draws its own. */
.tier-card::before { content: ""; position: absolute; top: 0; left: 1.6rem; width: 3rem; height: 2px; z-index: 1; }
.fleet-card--standard::after, .fleet-card--premium::after, .fleet-card--luxury::after, .tier-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: 2px;
    border-radius: inherit;
    pointer-events: none;
    opacity: .72;
    background: conic-gradient(from var(--ledo-firefly),
        transparent 0deg, transparent 315deg,
        color-mix(in srgb, var(--tier-deep) 60%, transparent) 318deg,
        color-mix(in srgb, var(--tier-mid) 72%, transparent) 328deg,
        color-mix(in srgb, var(--tier-core) 92%, transparent) 335deg,
        color-mix(in srgb, var(--tier-mid) 72%, transparent) 342deg,
        color-mix(in srgb, var(--tier-deep) 60%, transparent) 348deg,
        transparent 351deg, transparent 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    animation: ledo-firefly-run 3.2s linear infinite;
}
@media (hover: hover) {
    .fleet-card--standard:hover, .fleet-card--premium:hover, .fleet-card--luxury:hover, .tier-card:hover {
        transform: translateY(-7px);
        border-color: var(--tier-mid);
        box-shadow: inset 0 1px 0 rgb(255 255 255 / 14%), 0 1.2rem 2.6rem rgb(0 0 0 / 40%);
    }
}
@media (prefers-reduced-motion: reduce) {
    .fleet-card--standard, .fleet-card--premium, .fleet-card--luxury, .tier-card { transform: none; }
    .fleet-card--standard::after, .fleet-card--premium::after, .fleet-card--luxury::after, .tier-card::after { animation: none; }
}

/* THE SHEEN, the other half of System.A's card: a diagonal band of light that
   sweeps across when the cursor arrives. It rides an element of its own because
   both pseudo-elements are taken - the bar at the top and the firefly rim - and
   it is parked off the card until then, so nothing moves on a page nobody is
   pointing at. The firefly brightens and quickens at the same moment, which is
   what makes the card feel alive under the hand. */
.fleet-sheen {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    border-radius: inherit;
    background: linear-gradient(105deg, transparent 22%, color-mix(in srgb, var(--tier-core, #c5e4ff) 30%, transparent) 49%, transparent 70%);
    background-size: 250% 100%;
    background-position: 130% 0;
    transition: background-position .55s ease;
}
@media (hover: hover) {
    .fleet-card:hover .fleet-sheen { background-position: -30% 0; }
    .fleet-card--standard:hover::after, .fleet-card--premium:hover::after, .fleet-card--luxury:hover::after, .tier-card:hover::after {
        opacity: 1;
        animation-duration: 1.6s;
    }
}
@media (prefers-reduced-motion: reduce) {
    .fleet-sheen { display: none; }
}

.fleet-card .fleet-category { font-size: .7rem; }
.fleet-card h3 { font-size: clamp(1.8rem, 2.7vw, 2.75rem); letter-spacing: -.055em; font-weight: 500; margin: .6rem 0 1rem; }
.fleet-card p { margin-block: .5rem 1rem; font-size: .82rem; line-height: 1.8; }
.fleet-card .fleet-alternative { font-size: .74rem; margin-top: 0; }
/* THE BUTTON WEARS THE COLOUR OF THE CAR IT BOOKS (Owner, 2026-09-23: "why
   is the button blue on a green card?"). Green for Standard, blue for
   Premium, burgundy for Luxury - and the card already says which through
   `--tier-mid` and `--tier-core`, so this is one rule reading those, not
   three buttons written out. Luxury used to be the only one spelled out by
   hand, which is exactly why the other two were both blue. */
.fleet-book { position: relative; display: inline-flex; align-self: center; justify-content: center; align-items: center; gap: .65rem; width: min(100%, 12rem); min-height: 2.85rem; margin-top: auto; padding: .7rem 1rem; overflow: hidden; border: 1px solid color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 48%, transparent); border-radius: .38rem; background: linear-gradient(135deg, color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 17%, transparent), color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 5%, transparent)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 12%), 0 .6rem 1.3rem rgb(0 0 0 / 18%); color: var(--tier-core, var(--ice)); font-size: .76rem; font-weight: 700; letter-spacing: .04em; text-decoration: none; transition: transform .2s, border-color .2s, box-shadow .2s, background .2s; }
.fleet-book::before { position: absolute; inset: 0; content: ""; background: linear-gradient(105deg, transparent 22%, rgb(197 228 255 / 32%) 49%, transparent 70%); transform: translateX(-125%); transition: transform .45s ease; }
.fleet-book span { position: relative; color: var(--tier-core, var(--blue-bright)); font-size: 1.05rem; transition: transform .2s; }
@media (hover: hover) { .fleet-book:hover { border-color: color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 85%, transparent); background: linear-gradient(135deg, color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 30%, transparent), color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 10%, transparent)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 20%), 0 .85rem 1.7rem color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 20%, transparent); transform: translateY(-2px); } .fleet-book:hover::before { transform: translateX(125%); } .fleet-book:hover span { transform: translate(2px,-2px); } }
@media (hover: hover) { .fleet-card:hover { border-color: color-mix(in srgb, var(--blue-bright) 45%, transparent); transform: translateY(-3px); } }
/* All CTA controls use the fleet-card button as their exact visual reference. */
/* ONE SIZE FOR EVERY BUTTON ON THE SITE (Owner, 2026-09-17), the hero's:
   46px tall, 16px of padding either side, and one width.
   The width is measured, not chosen. The longest label any button carries is
   "Se hvordan det virker" in Norwegian, 133px at this size - 138px now that
   every word starts with a capital (Owner, 2026-09-23) - so 10.8rem holds
   every label in all four languages with the hero's own padding still around
   it. Change a label, or the capitalisation, and this is the number to
   re-measure: at 10.6rem that one label wrapped onto a second line.
   The booking artwork in the header is not in this: it is a picture with its
   own frame, not a button with a word in it. */
:root { --button-width: 10.8rem; }
.button, .fleet-book, .footer-cta, .submit { width: var(--button-width); }
/* No forced capitals (Owner, 2026-10-15, undoing 2026-09-23): a label shows
   the casing it is written in, in all four languages. */
.button, .footer-cta, .nav-cta { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .65rem; min-height: 2.85rem; padding: .7rem 1rem; overflow: hidden; border: 1px solid color-mix(in srgb, var(--blue-bright) 48%, transparent); border-radius: .38rem; background: linear-gradient(135deg, color-mix(in srgb, var(--blue) 17%, transparent), color-mix(in srgb, var(--blue) 5%, transparent)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 12%), 0 .6rem 1.3rem rgb(0 0 0 / 18%); color: var(--ice); font-size: .76rem; font-weight: 700; letter-spacing: .04em; text-decoration: none; transition: transform .2s, border-color .2s, box-shadow .2s, background .2s; }
/* The submit button is the only one that has to centre itself inside a plain
   block, and auto margins do nothing to an inline-level box - which is what
   every button here is. It becomes block-level flex so the margins can work,
   and it says so AFTER the rule that makes every button inline: same
   specificity, so order is what decides. */
.submit { display: flex; margin-inline: auto; }
.button-primary, .button-quiet { border-color: color-mix(in srgb, var(--blue-bright) 48%, transparent); background: linear-gradient(135deg, color-mix(in srgb, var(--blue) 17%, transparent), color-mix(in srgb, var(--blue) 5%, transparent)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 12%), 0 .6rem 1.3rem rgb(0 0 0 / 18%); color: var(--ice); }
.button::before, .footer-cta::before, .nav-cta::before { position: absolute; inset: 0; content: ""; background: linear-gradient(105deg, transparent 22%, rgb(197 228 255 / 32%) 49%, transparent 70%); transform: translateX(-125%); transition: transform .45s ease; }
.button > span, .footer-cta > span, .nav-cta > span { position: relative; color: var(--blue-bright); font-size: 1.05rem; transition: transform .2s; }
.nav-cta { min-height: 2.55rem; padding: .42rem .48rem .42rem .82rem; gap: .65rem; border-color: rgb(107 185 255 / 62%); border-radius: .45rem; background: linear-gradient(135deg, rgb(22 48 75 / 88%), rgb(8 15 25 / 86%)); box-shadow: inset 0 1px 0 rgb(197 228 255 / 18%), 0 .4rem 1rem rgb(0 0 0 / 18%); }
.nav-cta-label { color: var(--ice) !important; font-size: .7rem !important; letter-spacing: .055em; }
.nav-cta-mark { display: grid; width: 1.55rem; aspect-ratio: 1; place-items: center; border: 1px solid color-mix(in srgb, var(--blue-bright) 74%, transparent); border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--blue) 24%, transparent), transparent 68%); box-shadow: 0 0 .65rem color-mix(in srgb, var(--blue) 28%, transparent), inset 0 0 .4rem rgb(197 228 255 / 16%); }
.nav-cta-mark::before { width: .56rem; height: .38rem; content: ""; border-top: 1px solid var(--ice); border-right: 1px solid var(--ice); transform: translateX(-.08rem) rotate(45deg); }
.nav-cta-mark::after { width: .7rem; height: 1px; content: ""; margin-left: -.08rem; background: var(--ice); box-shadow: 0 0 .35rem var(--blue-bright); }
@media (hover: hover) { .button:hover, .footer-cta:hover, .nav-cta:hover { border-color: var(--blue-bright); background: linear-gradient(135deg, color-mix(in srgb, var(--blue) 30%, transparent), color-mix(in srgb, var(--blue) 10%, transparent)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 20%), 0 .85rem 1.7rem rgb(40 132 235 / 20%); color: var(--ice); transform: translateY(-2px); } .button:hover::before, .footer-cta:hover::before, .nav-cta:hover::before { transform: translateX(125%); } .button:hover > span, .footer-cta:hover > span, .nav-cta:hover > span { transform: translate(2px,-2px); } }
/* Calling a journey off is the one destructive thing a customer can do here, so
   it is the one control that is not blue. Same recipe as every other button -
   translucent wash, 1px edge, the sheen on hover - in burgundy, so it reads as
   part of the site rather than a warning sticker glued onto it. */
.button-danger, .button.button-danger { border-color: rgb(198 90 96 / 55%); background: linear-gradient(135deg, rgb(150 40 48 / 28%), rgb(150 40 48 / 10%)); color: #ffd9d9; }
@media (hover: hover) {
    .button-danger:hover, .button.button-danger:hover { border-color: rgb(226 120 126 / 85%); background: linear-gradient(135deg, rgb(178 48 58 / 42%), rgb(178 48 58 / 16%)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%), 0 .85rem 1.7rem rgb(120 20 30 / 28%); color: #ffe6e6; }
}
/* A button that is waiting for the visitor to change something. Dimmed rather
   than hidden, so the way to save stays visible while it is not yet available. */
.button[disabled] { opacity: .45; box-shadow: none; cursor: not-allowed; }
.button[disabled]:hover { transform: none; }
/* The "it worked" notice. The Owner liked the green frame and asked for the
   buttons' own finish on it: the same gradient, inset highlight and shadow, in
   green - and none of the things that would make it look clickable. */
.form-notice { border-color: rgb(120 220 150 / 48%); border-radius: .38rem; background: linear-gradient(135deg, rgb(120 220 150 / 16%), rgb(120 220 150 / 4%)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 10%); color: #cfeedd; font-size: .8rem; font-weight: 600; letter-spacing: .04em; text-align: center; transition: border-color .2s, background .2s, box-shadow .2s; }
/* It lights up under the cursor like everything else on this site (Owner,
   2026-09-16) - but the cursor stays an arrow. There is nothing to click here;
   this is the site telling you something, not offering you an action. */
/* THE FIREFLY, carried over from CulinEire (Owner, 2026-09-16).
   There it runs round a chef's avatar; the technique is the same one
   chef_battle.css calls `.rank-aura` - a lit wedge of a conic gradient, masked
   down to the rim so it reads as a light travelling along the frame rather than
   a glowing disc.
   ONE DIFFERENCE, AND IT MATTERS. CulinEire's ring is a CIRCLE, so it simply
   rotates the whole layer. These notices are rounded rectangles: rotating the
   box would drag the rim off the shape. So the box stays put and the gradient's
   own start angle is animated instead, which needs @property - a plain custom
   property is a string and does not interpolate. Where @property is missing the
   wedge simply sits still, and the notice looks as it did before. */
@property --ledo-firefly {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.form-notice { position: relative; }
.form-notice::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 0;
  padding: 1.4px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(from var(--ledo-firefly), transparent 0deg, rgb(168 245 198) 9deg, rgb(120 220 150 / 35%) 22deg, transparent 38deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  filter: drop-shadow(0 0 3px rgb(120 220 150 / 75%));
  animation: ledo-firefly-run 4.6s linear infinite;
}
.form-notice:hover::before { animation-duration: 2.4s; }

@keyframes ledo-firefly-run { to { --ledo-firefly: 360deg; } }

/* A light that runs is decoration; a visitor who asked for stillness keeps it. */
@media (prefers-reduced-motion: reduce) {
  .form-notice::before { animation: none; }
}

.form-notice:hover { border-color: rgb(120 220 150 / 70%); background: linear-gradient(135deg, rgb(120 220 150 / 22%), rgb(120 220 150 / 7%)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 16%), 0 .5rem 1.1rem rgb(0 0 0 / 22%); }
/* The hero's two buttons match each other for the same reason and by the same
   means - an inline grid of equal columns, as wide as the longer label. */
.hero-actions { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .8rem; }

/* ALL THE SAME WIDTH (Owner, 2026-09-16). An inline grid is only as wide as it
   needs to be, and equal `1fr` columns inside it all take the width of the
   widest label - so three buttons match without a number written anywhere. It
   centres itself, being inline inside a centred block. */
/* H1 THAT FITS ITS OWN COLUMN (Owner, 2026-09-16: no needless second line).
   The site's h1 is one clamp for every page - up to 73.6px at 1400px - and
   these pages are not the hero: their columns are 478 to 824px wide, so the
   headline broke in two for want of room rather than for want of brevity.
   Each size below is measured, not chosen: the widest that still puts the
   longest title of that page, in the language where it is longest, on one line.

     account card   "Create your LEDO account"       795px of 478  -> 44.3px max
     contact card   "Связаться с администрацией."    947px of 638  -> 49.6px max
     legal page     "Персональные данные"            749px of 736  -> 72.3px max
     confirmation   "Спасибо. Ваша заявка зарег..."  1320px of 824 -> 46.0px max

   (measured at 73.6px and scaled; the numbers below sit under each ceiling).
   The hero keeps its size and its two lines: that break is written into the
   markup and the second line is the blue half of the sentence. */
.account-card h1, .booking-intro h1 { font-size: clamp(1.9rem, 3.1vw, 2.6rem); }
.contact-card h1 { font-size: clamp(2rem, 3.4vw, 2.9rem); }
.legal h1 { font-size: clamp(2.1rem, 4.6vw, 4.3rem); }
.confirmation h1 { font-size: clamp(1.9rem, 3.2vw, 2.8rem); }

/* The legal pages. Read to find a clause, not for pleasure, so: a left edge, a
   measure that does not force the eye to travel, and headings that are findable
   by scanning rather than by size. */
.legal { max-width: 52rem; margin-inline: auto; }
.legal h1 { margin-bottom: .8rem; }
.legal-intro { max-width: 46rem; color: var(--muted); font-size: .95rem; line-height: 1.7; }
.legal-updated { margin: .4rem 0 0; color: var(--muted); font-size: .72rem; letter-spacing: .04em; text-transform: uppercase; }
.legal-section { margin-top: 2.2rem; }
.legal-section h2 { font-size: 1.05rem; letter-spacing: 0; }
.legal-section p { margin: .7rem 0 0; color: var(--muted); font-size: .85rem; line-height: 1.75; }
/* The three sister documents sit centred under the text (Owner, 2026-09-16).
   The row is an inline-grid, so `justify-content` moves the columns INSIDE it
   and leaves the row itself against the left edge: what centres the row is its
   own margin. */
/* The three sister documents sit centred under the text (Owner, 2026-09-16).
   `display: grid` rather than the inline-grid the row uses elsewhere: an
   inline-level box ignores `margin: auto`, which is why centring it by margin
   alone did nothing. Block-level, the auto margins centre the row and
   justify-content centres the buttons inside it. */
.legal .manage-actions { display: grid; justify-content: center; margin: 3rem auto 0; }
.footer-policies { display: flex; flex-wrap: wrap; gap: .3rem 1.1rem; margin: 0 0 .6rem; }
/* White over the footer picture (Owner, 2026-09-26: grey melted into it). */
.footer-policies a { color: var(--text); font-size: .72rem; text-decoration: none; }
.footer-policies a:hover { color: var(--ice); text-decoration: underline; }
/* Bearcave lights up a little under the pointer (Owner, 2026-09-26). */
.footer-maker__email strong { transition: text-shadow .2s ease; }
.footer-maker__email:hover strong, .footer-maker__email:focus-visible strong { text-shadow: 0 0 .55rem color-mix(in srgb, var(--blue-bright) 85%, transparent), 0 0 .15rem rgb(255 255 255 / 60%); }
.manage-actions { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .75rem; margin: 2rem 0 0; }
.manage-actions form { margin: 0; }
/* The rate notice: quiet, but it sits with the price, not in the small print
   at the bottom of a page nobody reads before pressing send. */
/* Centred, like the price it belongs to (Owner, 2026-09-16), and the consent
   line under it stands on the same axis rather than hanging at the left edge. */
/* The button under it was sitting ON the notice: the paragraph had no bottom
   margin and `.confirmation-return` no top one (Owner, 2026-09-16). Both ends
   of that gap are stated here so it is even, whether or not the notice shows. */
.quote-note--block { margin-block: 1.6rem; }
.confirmation-return { margin-top: 1.6rem; }
.quote-note { margin: .6rem auto 0; max-width: 34rem; color: var(--muted); font-size: .76rem; line-height: 1.6; text-align: center; }
.quote-note--block { max-width: 34rem; margin-inline: auto; text-align: center; }
/* Equal above and below, so the consent line sits between the price and the
   button rather than leaning towards one of them. */
.terms { margin-block: 1.3rem; justify-content: center; }
.form-actions { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .75rem; }
/* Centred throughout (Owner, 2026-09-15): the question, the terms, the line
   about payment and the two answers all sit on one axis. */
.confirm-dialog { width: min(100%, 30rem); padding: 1.8rem 1.6rem; text-align: center; border: 1px solid var(--line); border-radius: .6rem; background: linear-gradient(150deg, var(--panel), var(--night-soft)); color: var(--text); box-shadow: 0 1.6rem 3.4rem rgb(0 0 0 / 55%); }
/* The dialog takes focus when it opens, so it must not draw a ring around
   itself; the buttons inside keep theirs, in the site's own colours rather
   than the browser's blue - and the burgundy one rings burgundy. */
.confirm-dialog:focus { outline: none; }
.button:focus-visible { outline: 2px solid var(--blue-bright); outline-offset: 2px; }
.button-danger:focus-visible { outline-color: rgb(216 120 126 / 85%); }
.confirm-dialog::backdrop { background: rgb(4 7 12 / 72%); }
.confirm-dialog h2 { margin: 0 0 1rem; font-size: 1.25rem; letter-spacing: -.01em; line-height: 1.25; }
.confirm-dialog__terms { margin: 0 0 .8rem; padding: .85rem; border: 1px solid rgb(198 90 96 / 35%); border-radius: .35rem; background: rgb(150 40 48 / 12%); font-size: .82rem; line-height: 1.6; color: #ffd9d9; }
.confirm-dialog__fee { display: inline-block; margin-top: .45rem; font-size: 1.05rem; font-weight: 700; letter-spacing: .01em; }
.confirm-dialog__note { margin: 0 0 1.3rem; font-size: .76rem; line-height: 1.6; color: var(--muted); }
.confirm-dialog__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem; }
.confirm-dialog__actions form { margin: 0; }
.price-section { grid-template-columns: .8fr 1.2fr; gap: 3rem; }
/* THE TWO PANELS ARE ONE DESIGN (Owner, 2026-09-16), so they share the frame as
   well as the scrolling: same border, same radius, same inner margin. That last
   one is what the Owner measured - the price sat 32px from the panel's right
   edge and the plus sign 10, because only this panel had side padding.
   What is NOT shared is the vertical rhythm: the questions are deliberately
   tighter, halved earlier at his word. */
/* ONE PANEL FOR EVERY RIGHT-HAND BLOCK (Owner, 2026-09-16: give them all the
   same depth as the price list). Frame, corner, inner margin, wash and shadow
   come from here; what each block does inside it is its own business. */
.fare-list, .faq-list, .process .steps, .beyond .steps, .fare-table-wrap, .vehicle-extras {
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding-inline: 1.3rem;
    /* THE SAME SURFACE THE FLEET CARDS USE, and for the same reason: a
       translucent wash over a near-black page is still near-black, which is
       exactly what the Owner kept seeing. This one is opaque and visibly a
       panel. */
    background: linear-gradient(145deg, var(--panel), var(--night-soft));
    box-shadow: 0 1rem 2.4rem rgb(0 0 0 / 22%);
}
.process .steps, .beyond .steps { padding-block: 0; }
/* THE FOOTER'S CONTACT BLOCK IS NOT A PANEL (Owner, 2026-09-16: take it out of
   the container on desktop too). It used to borrow the frame every right-hand
   block on the page wears; in the footer that made a card floating inside a
   band that is already set apart by its own rule above. It keeps the column it
   stands in - it simply stops being boxed. */
.footer-maker { padding-block: 1rem 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
.fare-list article { gap: 1rem; padding: 1rem 0; }
.fare-list article:last-child { border-bottom: 0; }
.fare-list span { font-size: .82rem; line-height: 1.5; }
.fare-list small { font-size: .65rem; }
.fare-list strong { font-size: 1.12rem; font-variant-numeric: tabular-nums; }
/* The euro figure under the krone one, right-aligned with it, the way the
   class pages print it. It is not a class label, so it drops the uppercase
   tracking the left column's small wears. */
.fare-price { flex-shrink: 0; text-align: right; }
/* NOTHING CROSSES THE PAGE'S OWN EDGES (Owner, 2026-09-16). Draw a line down
   each side of the container and every band, rule and background has to stop
   there: this section used to run its panel and both hairlines the full width
   of the window, which made the page look like two different sites stacked.
   It keeps its darker ground - it is the one section that is a panel - but the
   panel is now exactly as wide as everything above and below it. */
.booking-section { max-width: var(--page-width); margin-inline: auto; padding: 4.5rem calc(var(--gutter) + var(--text-inset)); grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; background: linear-gradient(135deg, var(--night-soft), var(--night)); border-block: 1px solid var(--line); }
.booking-intro { top: 2rem; }
.booking-panel { border-radius: .6rem; background: linear-gradient(150deg, var(--panel), var(--night-soft)); box-shadow: 0 22px 60px rgb(0 0 0 / 18%); padding: 1.8rem; }
.privacy-note { margin-top: 1.5rem; border-bottom: 0; font-size: .85rem; }
.privacy-note span { font-size: .75rem; line-height: 1.6; }
fieldset { min-width: 0; gap: 1rem; margin-bottom: 1.7rem; }
legend { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 1rem; color: var(--blue-bright); }
.field { min-width: 0; }
label { font-size: .75rem; font-weight: 500; }
input, select, textarea { min-width: 0; max-width: 100%; border-color: var(--line); border-radius: .3rem; font-size: 1rem; min-height: 3rem; transition: border-color .2s, box-shadow .2s; }
textarea { min-height: 5rem; }
input:hover, select:hover, textarea:hover { border-color: rgb(220 238 255 / 28%); }
.terms label { font-size: .73rem; line-height: 1.65; text-align: left; }
.terms input, .return-toggle input { flex-shrink: 0; }
/* The own-route box is a row of its own, not a cell beside the date the way the return box is. */
.own-route-toggle { align-self: auto; min-height: 0; }
.turnstile { display: flex; justify-content: center; margin: 0 0 1rem; }
.booking-panel .turnstile { margin: 1rem 0 21px; } /* above the send button now, with the same air under it as over it (2026-11-05) */
.field-note { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: .75rem; line-height: 1.6; }
.route-preference { margin: .6rem 0 0; font-size: .78rem; color: var(--muted); cursor: pointer; }
.quote { border-radius: .35rem; padding: 1.1rem; }
.quote strong { font-size: 1.15rem; text-align: right; }
.faq { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; }
.faq > .section-heading, .faq > .faq-list { width: auto; margin-inline: 0; }
/* ONE LINE, IN EVERY LANGUAGE (Owner, 2026-09-16). These headings sit in
   columns of 465 to 621px at 1400px while the site's h2 is 73.6px, so most of
   them broke in two or three. 48px is the largest size at which every heading,
   in every language, still fits its own column - the binding cases being the
   English ones, which were also shortened where no heading size would have
   saved them ("Space and comfort for your journey." wanted 1100px of 496).
   The vw term carries this down as the columns narrow. */
/* The price section's heading is not inside a `.section-heading` - it is a bare
   <h2> in the first column - so it slipped past this rule and stayed at 73.6px,
   the only section heading still breaking in two. */
.section-heading h2, .booking-intro h2,
.price-section > div:first-child h2 { font-size: clamp(2rem, 3.4vw, 3rem); }
.faq .section-heading { max-width: none; }
.faq-list summary { font-size: .86rem; font-weight: 500; gap: 1rem; padding-block: .65rem; }
.faq-list summary span { flex-shrink: 0; }
/* The separators match the fare rows down to the curl at their ends: the same
   8px corner on the row, and no rule under the last one (Owner, 2026-09-16 -
   "I want it like the first one"). */
.faq-list details { border-radius: .5rem; }
.faq-list details:last-child { border-bottom: 0; }
.faq-list details[open] { border-color: color-mix(in srgb, var(--blue-bright) 40%, transparent); }
.faq-list p { font-size: .83rem; padding-right: 2rem; }
.closing { min-height: 0; max-width: var(--page-width); margin: 0 auto; padding: 2rem calc(var(--gutter) + var(--text-inset)) 2.25rem; border-top: 1px solid var(--line); background: radial-gradient(ellipse at bottom, color-mix(in srgb, var(--blue) 9%, transparent), transparent 70%); }

/* WHY HERE AND NOT BESIDE THE RULE THAT SHORTENS THE LINES: `.booking-section`
   and `.closing` set `background` as a shorthand further down this file, and a
   shorthand resets `background-size` to auto. These have to be read after them. */
/* AND THE PANELS' OWN BACKGROUNDS END THERE TOO (Owner, 2026-09-18: the line
   doubles and there is a gradient showing under it).

   Two blocks paint a background of their own, and it was drawn to the edge of
   the screen. Once the rules stopped at the gutter, the edge of that background
   carried on where the line had stopped: a second, fainter line, in the colour
   of the panel rather than of the rule. The background is now the width of the
   content, so the panel and the rule end on the same axis. */
.booking-section, .closing {
    background-size: calc(100% - 2 * var(--gutter)) 100%;
    background-position: center;
    background-repeat: no-repeat;
}

/* ONE LINE AT A SEAM, NOT TWO. The block of the booking form draws a rule under
   itself AND the section that follows draws one over itself, both at the same
   height: 1px of white at 12 per cent over another, which is what reads as a
   line that doubles. The seam belongs to the block below, like every other seam
   on the page; a booking block with nothing after it still has the footer's
   rule under it. */
.booking-section { border-bottom: 0; }
.closing h2 { margin-bottom: 1.4rem; }
/* The label goes left like every other on the site (Owner, 2026-09-16), while
   the sentence and the button under it stay centred. `.closing` is a grid that
   centres its items, so the eyebrow has to be PLACED, not just aligned; the
   block is page-width with the usual gutter, so this puts it on the same left
   edge as the labels in the sections above. */
.closing .eyebrow { margin-bottom: 1rem; justify-content: flex-start; justify-self: start; }
/* The footer keeps the guide: same columns, same gap as the sections above. */
/* The 3rem gap belongs BETWEEN the columns, not between the rows: down the
   page it put 66px of nothing between the last contact line and the hairline
   over the credits (Owner, 2026-09-16: too much air). Column gap stays, row
   gap is the air a rule needs to read as a separator and no more. */
.site-footer { position: relative; isolation: isolate; container-type: inline-size; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: start; max-width: var(--page-width); padding: 1.9rem calc(var(--gutter) + var(--text-inset)); gap: .55rem 3rem; text-align: left; font-size: .73rem; }
/* THE OWNER'S PICTURE UNDER THE FOOTER (2026-09-26): the footer keeps its
   size and its text keeps its place; the picture lies beneath, anchored so
   the car stands whole in the frame (86%, chosen on screen with the Owner),
   darkened at the top for the text and a little at the foot for the small
   print. On a phone it covers the tall footer too, as the Owner approved it,
   shifted left so the car stays in the narrow frame. */
.site-footer > .footer-art { position: absolute; z-index: -1; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 86%; pointer-events: none; }
.site-footer::after { content: ""; position: absolute; z-index: -1; inset: 0; background: linear-gradient(180deg, var(--night) 0%, rgb(7 11 18 / 78%) 35%, rgb(7 11 18 / 50%) 70%, rgb(7 11 18 / 72%) 100%); pointer-events: none; }
@media (max-width: 620px) { .site-footer > .footer-art { object-position: 28% 86%; } }
/* The picture ends where the footer's rule ends - one gutter in, on the
   content's edge - so nothing runs past the site (Owner, 2026-09-29:
   "everything even"). On a phone it stays full width, as approved. */
@media (min-width: 621px) {
    .site-footer > .footer-art, .site-footer::after { inset-inline: var(--gutter); }
    .site-footer > .footer-art { width: calc(100% - 2 * var(--gutter)); }
}
/* ONE INSET FOR ALL FOUR BLOCKS (Owner, 2026-09-16). The contact block used to
   start flush against the column while the block opposite it carried 1.3rem of
   padding, so the two halves of the footer began on different lines. They all
   share the inset now - address, contact block, credits and legal links - and
   the hairlines still run the full width, which is what tells the eye where
   the column is. */
@media (min-width: 1101px) { .footer-ledo { padding-left: 1.3rem; } }
.footer-ledo { text-align: left; }
/* THE THREE ICON ROWS STEP IN (Owner, 2026-09-16, marked on a screenshot).
   The two legal lines above them are text and start on the column's own edge;
   these three are a list with a mark in front of each, so they hang from a
   line of their own - the same 1.3rem the blocks themselves are inset by. */
.footer-details { justify-items: start; width: auto; gap: .25rem; margin-inline: 0; }
@media (min-width: 1101px) {
    .footer-details > .footer-line:not(.footer-line--legal) { padding-left: 1.3rem; }
}
.footer-details a { width: fit-content; text-decoration-color: color-mix(in srgb, var(--blue-bright) 30%, transparent); text-underline-offset: .22em; }
/* NO FLEX GAP HERE. The left column is a plain block whose children space
   themselves with margins; this one added 11.2px of gap on top of them, so the
   white line under the label sat 11px lower than its opposite number. Margins
   on both sides now, and no padding to shift the label either. */
.footer-maker { align-items: flex-start; justify-content: flex-start; gap: 0; margin: 0; padding: 0 1.3rem 1.1rem; text-align: left; font-size: .72rem; }
/* THE TWO COLUMNS SAY THEIR LINE THE SAME WAY (Owner, 2026-09-16). Each has a
   small blue label and one white line under it; the left one was set as small
   grey body text, so the pair read as two different kinds of thing. One rule
   now, on both. */
.footer-maker h2, .footer-ledo > p:not(.eyebrow) { margin: .4rem 0 .7rem; color: var(--ice); font-size: clamp(1rem, 1.45vw, 1.15rem); font-weight: 500; letter-spacing: -.02em; line-height: 1.25; }
.footer-maker > p:not(.footer-kicker) { max-width: 27rem; margin: 0; color: var(--muted); font-size: .78rem; line-height: 1.65; }
/* THE TWO COLUMN LABELS ARE ONE THING (Owner, 2026-09-16), so they are one
   rule: same size, same tracking, same blue. The wordmark was white, inline and
   11.68px against the kicker's blue 9.92px block, which is why the white lines
   under them sat 13px apart instead of on one line. */
/* THE FOOTER'S TWO LABELS ARE EYEBROWS (Owner, 2026-09-17: make them like the
   one at the top). They carry the class now, so the dash, the blue, the
   tracking and the left edge come from one place rather than from a copy that
   had already drifted - one was white and inline, the other blue and block. All
   that is left here is the size, which is a notch down from a section's. */
.footer-brand, .footer-kicker { margin: 0; }
/* Row two of the footer: the credits under the company's details, the legal
   links under the contact block, on one line and sharing one rule above them. */
/* THE SECOND ROW IS PLACED, THE FIRST IS NOT. Pinning the two columns to row 1
   is what broke the footer on a phone: with a single column and both of them
   claiming that row, auto-placement pushed the second one into an implicit
   column and the footer came apart. The first row places itself; only the row
   below it is told where to go, and on a phone that instruction is lifted. */
.footer-legal { grid-column: 1; grid-row: 2; }
.footer-policies { grid-column: 2; grid-row: 2; margin: 0; padding-top: .6rem; border-top: 1px solid var(--line); }
/* THE TWO BLOCKS ARE ONE PAIR, CENTRED (Owner, 2026-09-16: the same air left
   and right, and nothing inside either block touched). They used to be the
   footer grid's own two columns, so they were pinned to its edges and the wider
   right-hand column pushed the pair off the page's axis. Wrapped, they size to
   their content and the wrapper centres them; the credits and the legal links
   stay children of the footer grid, exactly where they were. */
@media (min-width: 1101px) {
    /* THE PAIR SPANS THE SITE (Owner, 2026-09-19, with arrows: push the two
       blocks out to the page's edges). The left block starts where every
       section's text starts and the right block ends where every right-hand
       panel ends; the air is between them, not around them. Each block still
       sizes to its content, capped as before. */
    .footer-top { grid-column: 1 / -1; display: grid; grid-template-columns: auto auto;
        justify-content: space-between; width: 100%; column-gap: 3rem; }
    .footer-top > .footer-maker { max-width: 30rem; }
    .footer-top > .footer-ledo { max-width: 34rem; }
    /* The button in the middle of its block (Owner, 2026-09-19). */
    .footer-top > .footer-maker .footer-cta { align-self: center; }
    /* THE BUTTON ENDS ON THE SAME LINE AS THE EMAIL (Owner, 2026-09-18). It sat
       13px high: the button carried 1rem of margin under it and the block
       another 1.1rem of padding, while the contacts column simply ended at its
       last line. Both are taken off and the button is pushed to the foot of its
       column instead, so the two columns close together. Stated as a rule and
       not as 13px: the columns are stretched to the taller of the two, so the
       foot of the block IS the foot of the contacts, whatever either of them
       comes to say in another language. */
    .footer-top > .footer-maker { padding-bottom: 0; }
    .footer-top > .footer-maker .footer-cta { margin-top: auto; margin-bottom: 0; }
    /* THE SAME AIR ABOVE THE PAIR AS BELOW IT (Owner, 2026-09-18). The footer's
       own padding puts 1.9rem between its top rule and the pair; underneath,
       the grid's row gap left only .55rem before the rule over the credits, so
       the block sat high in its own band. One number now, read from the top
       side, so the pair is centred in the space between the two rules. */
    .site-footer { row-gap: 1.9rem; }
}
/* One column on a phone: the wrapper steps out of the way entirely. */
@media (max-width: 1100px) { .footer-top { display: contents; } }

/* THE LAST LINE OF THE PAGE, in three places (Owner, 2026-09-16): the credits
   on the left where they always were, the legal links pushed to the far right
   with the same 1.3rem inset mirrored, and the copyright alone on its own line,
   centred on the page. The credits row spans both columns so that "centred"
   means centred on the page and not inside a column; the links sit in the
   right-hand column of the same row, which is what puts them level with the
   credits rather than under them. */
/* Written against `.site-footer` on purpose: the rules these override sit
   later in this file, and a media query adds no weight of its own. */
@media (min-width: 1101px) {
    .site-footer .footer-legal { grid-column: 1 / -1; }
    .site-footer .footer-legal > span:first-child { justify-self: start; padding-left: 1.3rem; }
    .site-footer .footer-legal > span:last-child { justify-self: center; }
    /* ONE RULE, NOT TWO ON TOP OF EACH OTHER (Owner, 2026-09-18: the line ends
       in a different colour). The two blocks began as neighbouring columns,
       each drawing its own half of the rule above row two. The credits then
       took the full width so the copyright could be centred, and the legal
       links kept drawing over the right-hand end of it: white at 12% twice
       reads as 22%, so the last third of the line was brighter. The rule
       belongs to the block that spans the row. */
    .site-footer .footer-policies { grid-column: 2; grid-row: 2; justify-self: end;
        align-self: start; padding-right: 1.3rem; border-top: 0; }
}
.footer-legal { display: grid; gap: .45rem; width: 100%; margin-top: 0; padding-top: .6rem; border-top: 1px solid var(--line); color: var(--text); font-size: .67rem; line-height: 1.55; }
.contact-page { min-height: calc(100svh - 17rem); }
/* AS WIDE AS THE FOOTER, EXACTLY (Owner, 2026-09-19: the form was a little
   narrow and sat badly against it). The page and the footer already share
   `--page-width` and the same inline padding; the card had its own cap of
   44rem and so ended 4rem short on each side of every line beneath it. It
   fills the column now, and the page is held to the footer's width so the
   two edges are the same edge. */
.account-page.contact-page { max-width: var(--page-width); margin-inline: auto; }
.contact-card { width: 100%; }
.contact-card form { display: grid; gap: 1rem; }
.contact-card .turnstile { margin: .25rem 0 0; }
.account-page { min-height: calc(100svh - 20rem); padding: 3rem calc(var(--gutter) + var(--text-inset)); background: radial-gradient(ellipse at 50% 10%, color-mix(in srgb, var(--blue) 7%, transparent), transparent 62%); }
.account-card { border-radius: .6rem; padding: 2rem; background: linear-gradient(150deg, var(--panel), var(--night-soft)); }
/* CENTRED AT EVERY WIDTH (Owner, 2026-09-16), the same ruling as the
   confirmation page: the heading, the line under it, the notice and the button
   share one axis, while the eyebrow stays left as the page's label and the
   form's own fields keep their left edge - a label centred over a field it
   does not sit against stops telling you which field it belongs to.
   The heading also gains the bottom margin it never had: `h1` is reset to
   margin 0 with a 1.02 line-height, so a two-line title dropped its descenders
   straight onto the paragraph beneath it. */
.account-card { text-align: center; }
.account-card > .eyebrow { justify-content: flex-start; }
.account-card form { text-align: left; }
.account-card h1 { margin-bottom: .9rem; overflow-wrap: anywhere; }
/* The space above the button matches the card's own bottom padding, so the
   button sits in an even gap instead of leaning towards the text above it.
   Same clamp as the padding (ledo.css), not a number guessed to look close. */
.account-card .form-actions { margin-top: clamp(1.5rem, 5vw, 3rem); }
.account-card > p, .account-switch { font-size: .85rem; }
.account-card form { margin-top: 1.4rem; }
.account-card .account-switch, .account-switch--center { text-align: center; }
.password-field { position: relative; }
.password-field input { padding-right: 3rem; }
.password-toggle { position: absolute; top: 50%; right: .55rem; display: grid; width: 2.1rem; height: 2.1rem; place-items: center; transform: translateY(-50%); border: 0; border-radius: .3rem; background: transparent; color: var(--blue-bright); cursor: pointer; }
.password-toggle svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; }
.password-note { margin: .45rem 0 0; color: var(--muted); font-size: .72rem; line-height: 1.45; }
.password-toggle:hover, .password-toggle:focus-visible { background: color-mix(in srgb, var(--blue) 12%, transparent); outline: 0; }
.dashboard-card { width: min(100%, 64rem); }
.dashboard-book { display: flex; justify-content: center; margin-top: 2rem; }
.journey-card { border-radius: .4rem; padding: 1.4rem; border-left: 2px solid var(--blue); }
.journey-card strong { font-size: .88rem; line-height: 1.5; }
.journey-card form { margin-top: .5rem; }
.empty-state { padding: 1.4rem; border: 1px dashed var(--line); border-radius: .4rem; line-height: 1.7; }
/* CENTRED AT EVERY WIDTH (Owner, 2026-09-16). It used to centre only on a
   narrow screen, so on a desktop the eyebrow and the heading hung left while
   the line under them was already centred - two axes on one short page.
   The facts below keep their own alignment: they are a label/value grid, and
   centring those would break the column the eye follows down.
   THE EYEBROW STAYS LEFT on a wide screen (Owner, 2026-09-16) - it is a label
   for the page, not part of the announcement, and the rule that centres it on
   a narrow one is the old one, further down, untouched. */
.confirmation { min-height: 65svh; padding-top: 4rem; text-align: center; }
.confirmation h1 { width: 100%; }
.confirmation > p:not(.eyebrow) { margin-inline: auto; }
.confirmation .detail-list { text-align: left; }
.confirmation-notice { margin-inline: auto; text-align: center; }
.confirmation-return { display: flex; width: fit-content; margin-inline: auto; }
/* Centred, with the same air above and below it (Owner, 2026-09-16). It had
   1.3rem on top from ledo.css and nothing underneath, so it sat 32px below the
   sentence and 11px above the policy links. Both sides are stated here. */
/* The button sits where the block's own lines start. It used to be pinned to
   the page's axis so that it stood exactly under "Order a ride"; that was only
   possible while the block was the footer grid's right-hand column. Now the
   two blocks are centred as a pair (Owner, 2026-09-16), the block itself is no
   longer symmetrical about the page, and the two cannot both be true. The
   pair's centring won. */
/* Mirrored to the right edge of its block (Owner, 2026-09-16), with the same
   inset it had on the left: the block's own padding is equal on both sides, so
   flex-end alone puts the button 1.3rem from the right, exactly as far in as
   it used to sit from the left. On a phone the button is the width of the
   column, where "which side" does not arise. */
.footer-maker .footer-cta { align-self: center; margin-block: 1rem; } /* centred at every width, as the wide layout already was (Owner, 2026-09-19 and 2026-11-04) */
.footer-policies { margin-top: 0; }
.language-picker { margin: 0; }
.language-picker summary { min-height: 2.25rem; }
.language-picker__menu { gap: .15rem; z-index: 30; }
.language-picker__menu a { min-height: 2.75rem; }
@media (max-width: 1100px) {
    /* ONE ROW. The nav used to drop to a second, full-width row with a rule
       above it, which read as an empty band once the links went behind the
       burger. Brand, artwork, burger and language now share row one. */
    /* 1fr auto 1fr puts the booking artwork in the middle of the row, with
       the brand and the language picker holding equal space either side. */
    .site-header { grid-template-columns: 1fr auto 1fr; gap: .5rem .7rem; padding-block: .75rem; }
    .site-header > .brand { justify-self: start; }
    .site-header > nav { grid-column: 2; grid-row: 1; justify-content: center; gap: .5rem; flex-wrap: nowrap; padding-top: 0; border-top: 0; }
    /* Only reached if nav.js did not run: the account links keep a row of
       their own rather than disappearing. */
    .site-header > .header-account { grid-column: 1 / -1; grid-row: 2; justify-content: flex-end; gap: .9rem; }
    /* The artwork stands at the right end of its cell, so the burger - placed
       at the cell's end - is always at the artwork's end, whatever the cell's
       width. 15rem here; the phone narrows it further below. */
    /* The wrap is what is capped; the artwork fills the wrap. nav-booking.css
       loads after this file and sets the artwork's width 19rem, so the cap
       lives on the wrap where that cannot reach. Centred in its cell: when the
       row is wider than the cap the air goes either side, not all to one. */
    .site-header > nav { justify-content: center; }
    .nav-cta-wrap { width: 100%; max-width: 15rem; }
    /* THE BURGER IS PART OF THE BOOKING BUTTON (Owner, 2026-09-19: inside the
       button, with the firefly, and in proportion at every size). The two
       share `.nav-cta-wrap`; the burger is positioned against that wrap, 5px
       off the frame's right edge, and its size is the wrap's height less
       10px - so it is always the button's height minus a 5px margin, whatever
       width the button came out at. A round plate the colour of the artwork's
       own night, with the button's own light running its rim. */
    .header-right { display: contents; }
    .header-prefs { grid-column: 3; grid-row: 1; justify-self: end; align-self: center; }
    .nav-cta-wrap { position: relative; display: flex; flex: 0 1 auto; min-width: 0; }
    /* max-width, not width: nav-booking.css loads later and says width 19rem
       and no shrinking. A cap it never sets holds the artwork to the wrap. */
    .site-header .nav-cta-art { max-width: 100%; }
    .nav-toggle {
        position: absolute;
        top: 50%;
        right: 5px;
        z-index: 3;
        height: calc(100% - 10px);
        aspect-ratio: 1;
        width: auto;
        transform: translateY(-50%);
        border: 1px solid color-mix(in srgb, var(--blue-bright) 55%, transparent);
        border-radius: 50%;
        background: #08131e;
        overflow: hidden;
    }
    .nav-toggle span { width: 40%; }
    .nav-toggle span::before { top: -.28rem; }
    .nav-toggle span::after { top: .28rem; }
    .nav-toggle::after {
        content: "";
        position: absolute;
        inset: 0;
        padding: 1.5px;
        border-radius: inherit;
        pointer-events: none;
        /* the button's own light, which is red now (Owner, 2026-09-19) */
        background: conic-gradient(from var(--ledo-firefly), transparent 0deg, rgb(255 214 214) 8deg, rgb(226 78 88 / 45%) 20deg, transparent 34deg);
        -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
        mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        mask-composite: exclude;
        filter: drop-shadow(0 0 3px rgb(226 78 88 / 85%));
        animation: ledo-firefly-run 5.2s linear infinite;
    }
    @media (prefers-reduced-motion: reduce) { .nav-toggle::after { animation: none; } }
    .site-header > nav a { display: inline-flex; }
    .site-header > nav .nav-cta { margin-left: 0; }
    .nav-toggle { display: inline-flex; }
    /* THE MENU CARD (Owner, 2026-09-16: make it properly premium). It is the
       same surface as every panel on this site - #111a28 to #0d1420, one
       hairline, one corner - with a firefly running its rim, which is this
       site's signature and already costs nothing: the property and the
       keyframes are shared.

       Every row is the same height and the same shape, and each one lights up
       under the finger as a rounded tile rather than as bare text. The account
       links, which nav.js moves in here at this width, are separated by one
       hairline with equal air either side, not by a gap that has to be
       guessed at.

       It opens with a short rise-and-fade; a visitor who asked for less motion
       simply gets it already there. */
    .nav-links {
        position: absolute;
        z-index: 40;
        /* CENTRED ON THE BURGER (Owner, 2026-09-16), not on the page: the button
           is what was pressed, so the card belongs under it. Both coordinates
           come from nav.js - the button and the panel are in different parents,
           so CSS can reach neither its centre nor its bottom edge. */
        top: calc(100% + .35rem);
        left: 0;
        right: auto;
        display: none;
        flex-direction: column;
        gap: 1px;
        width: max-content;
        min-width: 8.5rem;
        max-width: calc(100vw - 2 * var(--gutter));
        padding: .3rem;
        border: 1px solid var(--line);
        border-radius: .6rem;
        background: linear-gradient(145deg, var(--panel), var(--night-soft));
        box-shadow: 0 1.4rem 2.8rem rgb(0 0 0 / 55%), inset 0 1px 0 rgb(255 255 255 / 8%);
    }
    .nav-links.is-open { display: flex; animation: nav-menu-in .18s ease-out; }
    .nav-links::after {
        content: "";
        position: absolute;
        inset: 0;
        z-index: 1;
        padding: 1px;
        border-radius: inherit;
        pointer-events: none;
        opacity: .6;
        background: conic-gradient(from var(--ledo-firefly),
            transparent 0deg, transparent 318deg,
            rgb(20 60 100 / 55%) 321deg,
            color-mix(in srgb, var(--blue) 70%, transparent) 330deg,
            rgb(230 245 255 / 90%) 336deg,
            color-mix(in srgb, var(--blue) 70%, transparent) 342deg,
            transparent 350deg, transparent 360deg);
        -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
        mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        mask-composite: exclude;
        animation: ledo-firefly-run 4.4s linear infinite;
    }
    .site-header .nav-links.is-open a,
    .nav-links .nav-account-form button {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: .6rem;
        width: 100%;
        min-height: 2.15rem;
        padding: 0 .6rem;
        border: 0;
        border-radius: .42rem;
        background: none;
        color: var(--text);
        font-size: .76rem;
        letter-spacing: .01em;
        text-align: left;
        transition: background .18s ease, color .18s ease;
    }
    @media (hover: hover) {
        .site-header .nav-links.is-open a:hover,
        .nav-links .nav-account-form button:hover {
            background: color-mix(in srgb, var(--blue) 14%, transparent);
            color: var(--ice);
        }
    }
    .site-header .nav-links.is-open a:focus-visible,
    .nav-links .nav-account-form button:focus-visible {
        outline: 2px solid var(--blue-bright);
        outline-offset: -2px;
    }
    /* The account links are moved in here by nav.js on this width. */
    /* The account links are their own group: one hairline, the same air above
       it as below it. It used to read as a hole in the middle of the card. */
    .nav-links .header-account {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 1px;
        width: 100%;
        margin-top: .28rem;
        padding-top: .28rem;
        border-top: 1px solid var(--line);
    }
    .nav-links .nav-account-form { width: 100%; }

    @keyframes nav-menu-in {
        from { opacity: 0; transform: translateY(-.35rem); }
        to { opacity: 1; transform: none; }
    }
    @media (prefers-reduced-motion: reduce) {
        .nav-links.is-open { animation: none; }
        .nav-links::after { animation: none; }
    }
    .hero { min-height: 36rem; padding-block: 3rem; }
}
@media (max-width: 900px) {
    .nav-cta-wrap { max-width: 13rem; }
    .hero { grid-template-columns: 1.3fr .7fr; gap: 1.25rem; }
    .hero h1 { margin-inline: auto; }
    .hero-visual { min-height: 0; }
    .hero-visual .route-card { padding: 1rem; }
    .route-cities { gap: .4rem; }
    .trust-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-inline: var(--gutter); }
    .trust-strip article { padding: 1rem .75rem; align-items: flex-start; }
    .trust-strip article > span { display: none; }
    .trust-strip article + article { border-top: 0; border-left: 1px solid var(--line); }
    .section { padding-block: 2.5rem; }
    .section + .section { padding-top: 1.75rem; }
    .trust-strip + .section { padding-top: 4.25rem; }
    .process, .beyond, .price-section, .booking-section, .faq, .fleet-header { grid-template-columns: 1fr; gap: 1.75rem; }
    .steps { margin-top: 0; }
    .steps article { padding: 1rem 0; }
    .steps h3 { margin: 0 0 .35rem; }
    .fleet-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .7rem; }
    .fleet-card { padding: 1rem; }
    .fleet-card h3 { font-size: 1.8rem; }
    .fleet-index { margin-bottom: 1.5rem; }
    .booking-intro { position: static; }
    .booking-section { padding-block: 2.5rem; }
    .privacy-note { margin-top: 1rem; padding-block: .8rem 0; }
    .closing { padding-top: 1.75rem; padding-bottom: 2rem; }
    /* ONE EDGE ON EVERY NARROW SCREEN (Owner, 2026-09-18: the headings float, sometimes
       left and sometimes centred, and it is not one page - it is the site).

       It was true, and it came from this file: some introductions were set as
       centred compositions and the sections around them were not, so reading
       down a narrow screen the text kept changing which edge it started from.
       A phone is read down one column; one column has one edge. Every label,
       heading and paragraph starts at the left, and the only things still
       centred are the ones he centred himself - the buttons and the small
       print at the very bottom.

       The rules that centred them are not overridden further down, they are
       gone: an override would have left two answers in the file for anyone
       reading it later. */
    .eyebrow, .confirmation > .eyebrow { justify-content: flex-start; }
    .hero-copy, .fleet, .price-section > div:first-child,
    .booking-intro, .account-card, .confirmation, .closing,
    .section-heading, .steps article, .privacy-note, .route-card p,
    .account-card > h1, .account-card > p:not(.form-notice),
    .hero h1, .closing h2, .confirmation h1, .journey-heading { text-align: left; }
    /* The closing block is a grid that packed its rows to the middle, so a
       heading set to the left still started wherever its own text happened to
       end. The rows take the full column; the button inside keeps its own
       auto margins and stays on the page's axis, where he put it. */
    .closing { justify-items: stretch; }
    /* The hero's pair was centred by the centring of the block around it, which
       has just gone. He asked for those buttons on the page's axis on the 17th
       and that has not changed, so they say it themselves now. */
    .hero-actions { display: grid; margin-inline: auto; }
}
@media (max-width: 620px) {
    /* Three equal columns do not fit a phone; stacked, they are still equal.
       `justify-items` is what keeps them on the page's axis: the row is 17rem
       wide and a button is 13rem since the buttons narrowed, so without it the
       buttons sit against the row's left edge and the hero's pair reads as
       pushed aside (Owner, 2026-09-17). The row itself was already centred;
       it was the buttons inside it that were not. */
    .manage-actions, .form-actions, .hero-actions { grid-auto-flow: row; width: min(100%, 17rem); justify-items: center; }

    /* The top row now carries the account links as well as the brand and
       the language picker, and below this width the three together are
       wider than the header - measured, the right gutter had gone to 0 and
       the language pill sat flush against the screen edge. The wordmark is
       what gives way: the logo mark still carries the brand, and the two
       things a visitor came to press keep their room. */
    .brand span { display: none; }
    .header-account { gap: .75rem; }

    /* THE BOOKING ARTWORK IS ON THE PHONE TOO (Owner, 2026-09-19: "it is
       beautiful and must load at once, between the logo and the burger, at a
       size chosen exactly"). It had been there all along at 0 x 0: the middle
       column was `auto`, the artwork inside it was `width: 100%`, and each
       waited on the other. The middle column is now the row's remaining space
       and the artwork fills it.

       Measured on a 375px screen: 325px inside the padding, the burger and
       the language pill take 127 and the emblem took 90, which left 86px -
       a 19px-tall button. So the emblem comes down to 4rem here (the wordmark
       is already gone at this width, the mark still says who this is), the
       pill loses its chevron, and the gaps tighten, which gives the artwork
       about 135px: 30px tall, its frame and its light both legible. */
    /* THE BUTTON GETS THE MOST THE ROW CAN GIVE (Owner, 2026-09-19: it reads
       poorly on a phone, use the space). Everything else in the row gives a
       little: the header's side padding comes in from 25px to 16px, the
       emblem from 64px to 56px, the language pill loses its chevron and some
       padding, the gaps sit at 8px. On a 375px screen that takes the button
       from 184px wide to 219px, and 41px tall to 49px; the cap rises to 16rem
       so a wider phone keeps growing it. */
    /* And five percent more (Owner, 2026-09-19): padding 16 to 12px, emblem
       56 to 50px, gaps 8 to 6px - 18px on a 375px row, which is the 5%. */
    .site-header { grid-template-columns: auto minmax(0, 1fr) auto; gap: .375rem; padding-inline: .75rem; }
    .brand-logo { width: 3.125rem; height: 3.125rem; }
    .site-header > nav { gap: .4rem; }
    .nav-cta-wrap { max-width: min(100%, 16rem); }
    .language-picker__chevron { display: none; }
    .language-picker summary { gap: .3rem; padding-inline: .45rem; min-height: 2.1rem; }
    /* No room in the header row without shrinking the booking button by a
       third: on a phone the switch stands beside Price in the burger. */
    .header-prefs > .currency-switch { display: none; }
    .nav-price-row { display: flex; align-items: center; gap: .5rem; }
    .nav-price-row > a { flex: 1 1 auto; }
    .currency-switch--burger { display: inline-flex; flex: 0 0 auto; }


    /* The links are not dropped any more - they live behind the burger. */
    .site-header > nav a, .header-account a, .nav-account-form button { font-size: .73rem; }
    .hero { grid-template-columns: 1fr; gap: 1.4rem; min-height: 0; padding-block: 2rem 1.5rem; }
    .hero::before { background: linear-gradient(90deg, rgb(7 11 18 / 94%), rgb(7 11 18 / 58%)), linear-gradient(0deg, var(--night), transparent 60%); }
    .hero-landscape { object-position: 72% center; }
    /* 14ch was what broke "Частный трансфер" across two lines on a phone: the
       cap, not the type size. On one narrow column there is nothing to hold the
       line back from, so the cap goes and the type scales with the viewport
       until the longest line fits. */
    .hero h1 { max-width: none; font-size: clamp(1.9rem, 8.6vw, 2.9rem); }
    .hero .eyebrow { margin-bottom: 1.2rem; }
    .hero-lead { font-size: .9rem; line-height: 1.7; margin-block: 1.2rem; }
    .hero-actions { gap: .65rem; }
    .hero-actions .button { font-size: .76rem; padding-inline: 1rem; gap: 1rem; min-height: 2.9rem; }
    .hero-note { font-size: .68rem; margin-top: .8rem; }
    .hero-visual { padding-top: 0; }
    .hero-signature { display: none; }
    .hero-visual .route-card { max-width: none; padding: .9rem 1rem; background: rgb(7 11 18 / 42%); }
    .route-cities { font-size: .78rem; }
    .route-line { margin-bottom: .65rem; }
    .route-card p { margin-top: .6rem; padding-top: .6rem; font-size: .68rem; }
    /* ledo.css centres `.section-heading` on a narrow screen too, so taking it
       out of premium's own list was not enough - it needs saying. */
    .section-heading { text-align: left; }
    .section-heading .eyebrow { justify-content: flex-start; }

    /* A step reads off the left edge: the number, the title, then the line
       under it (Owner, 2026-09-16). Centred, the description floated under a
       title it belonged to with nothing to line up against. */
    .steps article { text-align: left; }

    /* ONE LINE PER ITEM (Owner, 2026-09-16): the number, then the words, read
       left to right off one edge. Stacking the badge above the text turned
       three short facts into six lines of page for nothing. */
    .trust-strip { grid-template-columns: 1fr; }
    .trust-strip article { flex-direction: row; align-items: center; gap: .7rem; padding: .75rem 1rem; text-align: left; }
    .trust-strip article > span { display: grid; width: 1.7rem; height: 1.7rem; }
    .trust-strip article + article { border-left: 0; border-top: 1px solid var(--line); }
    /* The longest of the three, "Личный ответ / Оператор проверяет доступность",
       needed 276px of the 265px a 375px phone leaves. Half a step down on the
       caption and a tighter gap buy the 14px, so all three read as one line;
       narrower than that it wraps rather than being cut. */
    .trust-strip article div { display: flex; align-items: baseline; flex-wrap: wrap; gap: .1rem .4rem; }
    .trust-strip small { font-size: .68rem; }
    .trust-strip small { margin-top: 0; }
    .section { padding-block: 1.75rem; }
    .section + .section { padding-top: 1.5rem; }
    .trust-strip + .section { padding-top: 3.25rem; }
    .booking-section { padding-bottom: 1.75rem; }
    .section .eyebrow { margin-bottom: 1rem; }
    .process, .price-section, .booking-section, .faq { gap: 1.25rem; }
    .steps article { grid-template-columns: 1.5rem 1fr; column-gap: 1rem; }
    .fleet-grid { grid-template-columns: 1fr; gap: .85rem; margin-top: 1.2rem; }
    .fleet-card { padding: 1.2rem; }
    .fleet-index { position: absolute; right: 1.2rem; top: 1.2rem; margin: 0; }
    .fleet-card .fleet-category { padding-right: 2.5rem; }
    .fleet-card h3 { font-size: 2.1rem; margin-bottom: .6rem; }
    .fleet-card p { margin-bottom: .7rem; }
    .fleet-book { padding-top: .75rem; }
    .fare-list { padding-inline: 1rem; }
    .fare-list article { flex-direction: row; align-items: center; gap: .75rem; }
    .fare-list span { font-size: .75rem; }
    .fare-list strong { font-size: .95rem; }
    .booking-panel { padding: 1.1rem; }
    fieldset { grid-template-columns: 1fr; }
    .field.full { grid-column: auto; }
    .quote { grid-template-columns: 1fr; gap: .5rem; }
    .quote strong, .quote small { grid-column: 1; text-align: left; }
    .closing { padding-top: 1.5rem; padding-bottom: 1.75rem; }
    .site-footer { grid-template-columns: 1fr; padding-block: 1.7rem; gap: 1.5rem; text-align: center; }
    .footer-ledo { text-align: center; }
    /* The wordmark and the "need help?" line are labels like any other: left,
       and in the same blue. The company's details sit under them, left, with a
       small indent of their own so the block reads as an address rather than as
       more of the sentence above it (Owner, 2026-09-16). */
    /* Both of these are boxes inside a centred parent, so alignment alone did
       nothing: the wordmark is an inline <span> that has to become a block
       before its own text-align means anything, and the kicker is a flex item
       that has to place itself. */
    /* THE FOOTER ON A PHONE (Owner, 2026-09-16: Bolt left it broken).
       One column, one alignment, one rhythm. Before this the wordmark was
       left, the address indented by 15px, the contact card centred and the
       legal lines centred again - four alignments in 600px of page, which is
       what made it read as rubble.

       Everything now starts on the same left edge, the way a phone screen is
       read, and the three groups are separated by a hairline each rather than
       by guessed margins. The two things a customer actually presses - the
       phone number and the email - are full-width rows with a real tap target
       (48px, the size a thumb needs), not 11px text links in a paragraph. */
    .site-footer { grid-template-columns: 1fr; gap: 0; padding: 2rem calc(var(--gutter) + var(--text-inset));
        text-align: left; font-size: .82rem; }
    /* The wide layout places these two side by side in row two; on one column
       every block simply follows the one above it. */
    .footer-ledo, .footer-maker, .footer-legal, .footer-policies { grid-column: 1; grid-row: auto; }
    /* THE CREDITS COME LAST (Owner, 2026-09-17). In one column the legal links
       belong with the rest of the site's own business, and the line about who
       built it closes the page. `order` moves them without touching the markup,
       which on a wide screen still puts the credits beside the links where the
       Owner asked for them. */
    .footer-policies { order: 1; }
    .footer-legal { order: 2; }
    .footer-ledo, .footer-maker { text-align: left; }
    /* The credits and the four legal links are the page's small print, not part
       of either column, so they sit on its axis (Owner, 2026-09-17). */
    .footer-legal { text-align: center; }
    /* The company's name over the footer is centred (Owner, 2026-09-16),
       against the site's usual rule that a label reads off the left edge: it
       is the heading of the whole footer, not a label for the block under it.
       The other kicker - "need help?" - stays left, because it does label the
       block under it. */
    /* Size, colour and tracking come from `.eyebrow`; these two only say where
       they sit, so the three labels on a phone are one label. */
    .footer-brand { width: 100%; }
    .footer-kicker { align-self: start; }
    .footer-ledo > p:not(.eyebrow) { margin: .45rem 0 1rem; font-size: 1.15rem; line-height: 1.25; }

    /* TWO GROUPS, NOT FIVE LOOSE LINES (Owner, 2026-09-18: the contacts are
       blown up and run together). The company's registration is one group and
       the three ways to reach it is another, and what separates them is a
       single piece of air - no rule, because he took the rules out of this
       block himself. Inside a group the lines sit close; between the groups
       they do not. The contact type was .92rem against the registration's
       .78rem, which is what made the lower half look inflated next to the
       upper one; .86rem still reads at arm's length on a phone. */
    .footer-details { justify-items: stretch; gap: 0; width: 100%; margin: 0; padding: 0; }
    .footer-line--legal { width: 100%; padding: .1rem 0; color: #aab6c4; font-size: .78rem; line-height: 1.45; }
    /* ONE HEIGHT FOR ALL THREE. The address is a line of text and the other two
       are links with a tap target, so they came out 29px and 39px next to each
       other - three facts in one group, drawn to two different rhythms. */
    .footer-details > :not(.footer-line--legal) { width: 100%; min-height: 2.1rem;
        padding: .2rem 0; font-size: .86rem; line-height: 1.4; }
    .footer-line--legal + :not(.footer-line--legal) { margin-top: .6rem; }
    /* A row a thumb can hit. No rules between them (Owner, 2026-09-16): the
       icons already say where each line starts, and five hairlines in a column
       of three facts read as a table nobody asked for. */
    /* Still a row a thumb can hit, and no taller than it needs to be: 2.9rem
       around a 23px line left 20px of nothing above and below the words. */
    a.footer-line:first-of-type { margin-top: 0; }
    .footer-details .footer-icon { width: 1.05rem; height: 1.05rem; }

    /* OUT OF THE FRAME (Owner, 2026-09-16). On a wide screen this block is a
       panel beside the address, and the frame is what makes the two columns
       read as a pair. On one column there is no pair: the card became a box
       drawn around a paragraph, narrower than everything above it. Here it is
       simply the next thing on the page, with a hairline where the previous
       group ends. */
    .footer-maker { align-items: stretch; padding-inline: 0;
        border: 0; border-top: 1px solid var(--line); border-radius: 0;
        background: none; box-shadow: none; text-align: left; }
    .footer-maker h2 { margin: .35rem 0 .5rem; font-size: 1.15rem; line-height: 1.25; }
    .footer-maker > p:not(.footer-kicker) { margin: 0; font-size: .85rem; line-height: 1.6; }
    /* Full width: on a phone a call to action that is not the width of the
       column looks like a mistake, and is harder to hit. */
    /* The same button as "Order a ride" at the end of the page (Owner,
       2026-09-16): same width cap, same height, same type - and since he asked
       again on the 17th, both of them narrower and both centred. 17rem was
       nearly the whole column; 13rem is a button. The cap lives in one place so
       the pair cannot drift, and `.closing .button` reads it too. */
    /* On a phone every button narrows together, by the same token. */
    :root { --button-width: min(100%, 13rem); }
    .footer-maker .footer-cta { align-self: center; min-height: 2.85rem; margin: 1rem auto 0; font-size: .76rem; }

    .footer-policies { justify-content: center; gap: .2rem 1.1rem; border-top: 1px solid var(--line); }
    .footer-policies a { min-height: 2.75rem; display: inline-flex; align-items: center; font-size: .82rem; }
    .footer-legal { gap: .35rem; font-size: .72rem; line-height: 1.6; justify-items: center; }
    /* ONE RHYTHM (Owner, 2026-09-16: the same air above the block as below it).
       Each group is separated from the one before by a hairline with 1.25rem
       either side of it, and the footer's own top and bottom padding is the
       same 2rem, so the column has no loose ends. */
    .footer-maker, .footer-legal, .footer-policies { margin-top: 1.25rem; padding-top: 1.25rem; }
    .account-page { padding-block: 1.5rem; }
    .account-card { padding: 1.3rem; }
    .hero h1, .hero-lead, .hero-note, .fleet-intro,
    .price-section > div:first-child > p, .booking-intro > p,
    .account-card > p:not(.form-notice), .confirmation > p:not(.eyebrow),
    .confirmation-notice { margin-inline: 0; }
    /* FAQ entries read as a list, not as a stack of centred labels. */
    .faq-list details { text-align: left; }
    .faq-list summary { justify-content: space-between; gap: 1rem; padding-inline: .75rem; }
    .faq-list details p { margin-inline: .75rem; padding-right: .75rem; }
    .journey-card { grid-template-columns: 1fr; }
    .journey-row { grid-template-columns: 1fr auto; }
    .journey-row__status { white-space: normal; }
    .confirmation { padding-top: 2rem; }
}
@media (prefers-reduced-motion: reduce) {
    .fleet-card:hover, .fleet-book:hover, .fleet-book:hover span, .button-primary:hover { transform: none; }
}


/* ONE CAR'S OWN PAGE (Owner, 2026-09-17: three buttons, three order forms with
   this car's prices and this car's capacity).

   The page wears the colour of the class it is about - green for Standard,
   blue for Premium, burgundy for Luxury - so a visitor arriving from a card
   recognises where they landed before reading a word. It gets there by joining
   the card on the line where those three tokens are already declared, near the
   top of this file, rather than by carrying a second copy of the values. */
.vehicle-hero { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; align-items: center; }
.vehicle-hero-text h1 { margin: .35rem 0 .9rem; font-size: clamp(2rem, 3.4vw, 3rem); line-height: 1.08; }
.vehicle-capacity { margin: 0; color: var(--ice); font-size: 1rem; line-height: 1.7; }
.vehicle-alternative { margin: .5rem 0 0; color: var(--muted); font-size: .8rem; line-height: 1.6; }
.vehicle-hero-text .button { margin-top: 1.5rem; }
/* The wash behind the car is its tier colour, faint. The image itself is a cut
   out on transparency, so without it the car floats on the page. */
.vehicle-hero picture { display: block; border-radius: .6rem; background: radial-gradient(120% 90% at 60% 40%, color-mix(in srgb, var(--tier-deep) 55%, transparent), transparent 72%); }
.vehicle-image { display: block; width: 100%; height: auto; }

.vehicle-prices { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; }
.vehicle-prices-body { display: grid; gap: 1.25rem; }

/* THE PRICE TABLE. It is a table because it is a grid of numbers read against
   two headings, and it carries the panel every right-hand block on this site
   wears. The krone figure is the price; the euro under it is the tariff's own
   second column, printed small because it is a reference, not the bill. */
/* overflow-x only: overflow-y is the scroll the panel shares with
   .fare-list (ledo.css) - the shorthand here would silently cancel it. */
.fare-table-wrap { overflow-x: hidden; }
/* The panel's shared fade (ledo.css) dims its top 2.2rem, which is where the
   column heads now stand - so this one fades at the bottom only. The heads
   are the one thing in here that must never read as greyed out. */
.fare-table-wrap { mask-image: linear-gradient(to bottom, #000 calc(100% - 2.2rem), transparent 100%); }
/* `separate`, not `collapse`, for one reason: a collapsed table throws away
   border-radius on its cells, and the row's separator has to CURL UP AT BOTH
   ENDS the way the home page's does (its rows are rounded boxes carrying
   only a bottom border). border-spacing 0 keeps the cells touching, so
   nothing else about the table moves. */
.fare-table { width: 100%; border-collapse: separate; border-spacing: 0; }
.fare-table-caption { margin: 0 0 .55rem; color: var(--muted); font-size: .72rem; line-height: 1.5; }
/* 1rem, not .85rem: the same vertical rhythm as a row of the home page's
   price list, which is the block this one is meant to read as (Owner,
   2026-09-22, after the two were finally compared part by part and not
   frame by frame). */
.fare-table th, .fare-table td { padding: 1rem 0; text-align: left; vertical-align: top; transition: background .18s ease; }
/* The column heads stay put while the rows move under them; the background
   is opaque so the rows pass behind, not through. The line beneath them is a
   real border now, not the inset shadow it used to be: a shadow cannot curl
   at its ends, and since the table went `separate` (see above) a border both
   travels with a stuck cell AND follows its corners (Owner, 2026-09-22). */
.fare-table thead th { position: sticky; top: 0; z-index: 1; background: var(--panel); border-bottom: 1px solid var(--line); color: var(--blue-bright); font-size: .62rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
/* …and the row passing under them DISSOLVES, it is not sliced (Owner,
   2026-09-22). The panel's own top fade is what does this on the home page;
   here the top of the panel is the head, so the fade hangs beneath it
   instead - same 2.2rem, same disappearing act, now against the head's own
   colour rather than the page's. */
.fare-table thead th::after {
    content: "";
    position: absolute;
    /* 100% of the containing block is its PADDING box, which is where the
       head's own border starts - +1px puts the fade under the line instead
       of painting over it. */
    left: 0; right: 0; top: calc(100% + 1px);
    height: 2.2rem;
    background: linear-gradient(to bottom, var(--panel), transparent);
    pointer-events: none;
}
.fare-table thead th small { display: block; margin-top: .2rem; color: var(--muted); font-size: .58rem; font-weight: 500; letter-spacing: .08em; }
/* The line goes UNDER every row but the last, which is where the home
   page's list puts it - not above every row but the first, which is what a
   table's own `tr + tr` habit produces. Same lines, drawn from the other
   side, so the two blocks divide their rows identically. */
@media (min-width: 621px) {
    .fare-table tbody th, .fare-table tbody td { border-bottom: 1px solid var(--line); }
    .fare-table tbody tr:last-child th, .fare-table tbody tr:last-child td { border-bottom: 0; }
    /* The row's outer corners are rounded, so the separator curls up where it
       ends and the hover tint has the same soft corners - both straight off
       `.fare-list article { border-radius: .5rem }`. */
    .fare-table tbody th { border-start-start-radius: .5rem; border-end-start-radius: .5rem; }
    .fare-table tbody td:last-child { border-start-end-radius: .5rem; border-end-end-radius: .5rem; }
    /* The head's line ends the same way a row's does. */
    .fare-table thead th:first-child { border-end-start-radius: .5rem; }
    .fare-table thead th:last-child { border-end-end-radius: .5rem; }
}
/* The row answers the cursor, the way a row of the price list does. The tint
   goes on the cells: a collapsed-border table ignores both background and
   radius on the <tr> itself in most browsers. */
@media (hover: hover) {
    .fare-table tbody tr:hover th, .fare-table tbody tr:hover td { background: rgb(255 255 255 / 3%); }
}
.fare-table thead th + th, .fare-table tbody th + td, .fare-table tbody td + td { padding-left: 1.3rem; }
/* Weight and tracking off the home page's own route line, not a table's
   default <th> bold: the same words should not be set two different ways on
   two pages of one site. */
.fare-table tbody th { color: var(--text); font-size: .82rem; font-weight: 400; letter-spacing: -.01em; line-height: 1.5; }
/* THE PRICE IS BLUE. It was white here and blue on the home page purely
   because nothing ever set a colour on it and <strong> brought its own 700
   with it - the loudest of the twelve differences between these two blocks,
   and the last one anybody would find by comparing their frames. */
.fare-table tbody strong { display: block; color: var(--blue-bright); font-size: 1.12rem; font-weight: 500; font-variant-numeric: tabular-nums; }
.fare-table-note { margin: 0; color: var(--muted); font-size: .72rem; line-height: 1.6; }

/* Waiting time and the per-km rate: the parts of the tariff that are not a
   route. Same panel, same two currencies, one line each. */
.vehicle-extras { margin: 0; padding-block: .3rem; list-style: none; }
.vehicle-extras li { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: .8rem 0; }
.vehicle-extras li + li { border-top: 1px solid var(--line); }
.vehicle-extras span { color: var(--muted); font-size: .78rem; }
/* Blue, like every other price on the site (Owner, 2026-09-22). Weight 500
   goes with it: 700 here was the <strong> tag's own default, the same
   accident that had the fare table's prices heavier than the home page's.
   The size stays .92rem - a rate per minute is a secondary figure, not a
   fare. */
.vehicle-extras strong { color: var(--blue-bright); font-size: .92rem; font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }

@media (max-width: 980px) {
    .vehicle-hero, .vehicle-prices { grid-template-columns: 1fr; gap: 1.75rem; }
    /* The car goes above the words it describes: a picture that arrives after
       the price of the thing it shows is a picture nobody looks at. */
    .vehicle-hero picture { order: -1; }
}

@media (max-width: 620px) {
    .vehicle-hero, .vehicle-prices { gap: 1.25rem; }
    .vehicle-hero-text h1 { font-size: 2rem; }
    .vehicle-capacity { font-size: .9rem; }
    /* A three-column table does not fit a phone, and scrolling it sideways
       hides the very column the visitor came for. Each row becomes its own
       block, and the two rate headings are reprinted beside their numbers from
       `data-label` - which is why the cells carry it. */
    .fare-table, .fare-table tbody, .fare-table tr, .fare-table th { display: block; }
    .fare-table thead { display: none; }
    /* No column heads on a phone, so nothing needs protecting from the top
       fade - the panel gets the same fade at both ends as every other one. */
    .fare-table-wrap { mask-image: linear-gradient(to bottom, transparent 0, #000 2.2rem, #000 calc(100% - 2.2rem), transparent 100%); }
    .fare-table th, .fare-table td { padding: .35rem 0; }
    .fare-table thead th + th, .fare-table tbody th + td, .fare-table tbody td + td { padding-left: 0; }
    .fare-table tbody tr { padding-block: .7rem; }
    .fare-table tbody tr + tr { border-top: 1px solid var(--line); }
    .fare-table tbody th { padding-bottom: .5rem; font-size: .8rem; }
    /* Two columns: the label, then the price flush right - kroner or euro,
       whichever the header's switch shows (the other is display:none). */
    .fare-table tbody td { display: grid; grid-template-columns: auto 1fr; gap: .15rem 1rem; align-items: baseline; }
    .fare-table tbody td::before { content: attr(data-label); grid-column: 1; color: var(--muted); font-size: .68rem; }
    .fare-table tbody td strong { grid-column: 2; text-align: right; }
    .fare-table-wrap, .vehicle-extras { padding-inline: 1rem; }
    .vehicle-extras li { padding-block: .65rem; }
}

/* The card's wash, said again down here: `.booking-panel` and `.account-card`
   both set `background` as a shorthand later in the file than the fleet rule,
   which would wipe the tint the class page and the form pages are meant to
   share with the blue car. Same specificity, so order is what decides. */
.tier-card {
    background-image: linear-gradient(135deg,
        color-mix(in srgb, var(--tier-mid) 16%, transparent),
        color-mix(in srgb, var(--tier-mid) 4%, transparent));
}

/* UNDER THE CURSOR THE FORM CARD GLOWS THE WAY THE HEADER'S "BOOK A RIDE"
   DOES (Owner, 2026-09-19): the same soft blue halo round the outline, the
   same slight brightening, the firefly quickening - and no further lift. That
   recipe lives in nav-booking.css on the artwork; these are its numbers. The
   fleet cards keep their own hover, the extra lift, which is right for a card
   you pick and wrong for a form you are filling in. */
@media (hover: hover) {
    .tier-card:hover {
        transform: translateY(-4px);
        filter: brightness(1.06);
        border-color: var(--tier-mid);
        box-shadow: 0 0 18px color-mix(in srgb, var(--blue) 24%, transparent), 0 .9rem 2rem rgb(0 0 0 / 35%);
    }
    .tier-card:hover::after { opacity: 1; animation-duration: 2.8s; }
}
@media (prefers-reduced-motion: reduce) {
    .tier-card:hover { transform: none; }
}

/* THE LABELS ARE LEGIBLE ON A DESKTOP (the client, 2026-09-18: "on the phone
   it is great, but on a computer the words at the top - Bilpark, Slik fungerer
   det - are very small"). 10.4px at arm's length is a caption, not a label.
   From the desktop breakpoint every eyebrow, and the two things cut from the
   same cloth - the class line on a fleet card and the legend in the form -
   come up two steps, to 12.8px. The phone keeps what she liked.
   LAST IN THE FILE ON PURPOSE: a media query adds no specificity, so this has
   to come after the base rules it raises or the base rules win. */
@media (min-width: 1101px) {
    .eyebrow, .fleet-card .fleet-category, legend { font-size: .8rem; }
}


/* THE MAP ON THE OWN-ROUTE PAGE (Owner, 2026-09-19, after maps.png): the
   site's night, blue roads, the route as a glowing line, the panel framed in
   the same light as the other panels. The block sits above the fields and
   the estimate reads as one line of light under the map. */
.route-map-block { display: grid; gap: .75rem; margin-bottom: 1.25rem; }
/* The same map inside the booking form (Owner, 2026-09-24): the fieldset's own
   gap already spaces it from the next row. */
.field.route-map-block { margin-bottom: 0; }
.route-map {
    height: clamp(16rem, 42vw, 24rem);
    border-radius: 1rem;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 45%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--blue) 12%, transparent) inset, 0 0 22px color-mix(in srgb, var(--blue) 18%, transparent);
    background: #070b12;
    overflow: hidden;
    transition: border-radius .3s ease, box-shadow .3s ease;   /* into and out of full screen */
}
.route-map-block.no-map .route-map { display: none; }
/* MapLibre's own sheet loads after this one and names its controls with two
   classes, so these carry three: the controls wear the night, not white. */
.route-map .maplibregl-ctrl.maplibregl-ctrl-attrib { background: rgb(7 11 18 / 78%); color: rgb(169 205 240 / 80%); font-size: .65rem; }
.route-map .maplibregl-ctrl.maplibregl-ctrl-attrib a { color: inherit; }
.route-map .maplibregl-ctrl.maplibregl-ctrl-attrib .maplibregl-ctrl-attrib-button { filter: invert(1) hue-rotate(180deg) opacity(.7); }
.route-map .maplibregl-ctrl.maplibregl-ctrl-group { background: rgb(7 11 18 / 85%); border: 1px solid color-mix(in srgb, var(--blue-bright) 35%, transparent); box-shadow: none; }
.route-map .maplibregl-ctrl.maplibregl-ctrl-group button + button { border-top-color: color-mix(in srgb, var(--blue-bright) 25%, transparent); }
.route-map .maplibregl-ctrl.maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) hue-rotate(180deg); }
.route-pin {
    position: relative;
    display: block; width: 16px; height: 16px; border-radius: 50%;
    background: #e6f3ff; border: 3px solid var(--blue);
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--blue) 25%, transparent), 0 0 18px color-mix(in srgb, var(--blue) 85%, transparent);
    cursor: grab;
    /* A finger, not a mouse (Owner, 2026-09-20: the first pin would not
       move on the iPhone). The browser must not read the drag as a page
       scroll or a long press, and the pin must be hit at 44px, not 16. */
    touch-action: none;
    -webkit-user-select: none; user-select: none;
    -webkit-touch-callout: none;
}
.route-pin::after { content: ""; position: absolute; inset: -14px; border-radius: 50%; }
.route-pin--destination { background: var(--blue); border-color: #e6f3ff; }
.route-estimate {
    display: grid; grid-template-columns: auto 1fr; gap: .15rem .9rem; align-items: baseline;
    padding: .85rem 1rem; border-radius: .75rem;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 30%, transparent); background: color-mix(in srgb, var(--blue) 6%, transparent);
}
.route-estimate__label { grid-column: 1; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted, #9fb6cf); }
.route-estimate__amount { grid-column: 2; font-size: clamp(1.15rem, 2.4vw, 1.5rem); color: #e6f3ff; min-height: 1.4em; }
.route-estimate__meta { grid-column: 2; font-size: .85rem; color: #a9cdf0; }
.route-estimate__caveat { grid-column: 1 / -1; font-size: .75rem; color: var(--text-muted, #9fb6cf); margin-top: .25rem; }
/* THE CONVOY NOTICE. Not an error - the journey is fine, it simply takes more
   than one car - so it wears the site's own blue rather than the red of a
   field that was filled in wrong (Owner, 2026-09-24). On a car's page it takes
   that car's colour with everything else. */
.convoy-notice {
    margin: 1.2rem 0 0;
    padding: 1rem 1.1rem;
    border: 1px solid color-mix(in srgb, var(--blue) 34%, transparent);
    border-radius: .55rem;
    background: color-mix(in srgb, var(--blue) 9%, transparent);
}
.convoy-notice[hidden] { display: none; }
.convoy-notice__title { margin: 0 0 .4rem; color: var(--blue-bright); font-size: .88rem; font-weight: 600; }
.convoy-notice p { margin: 0 0 .7rem; color: var(--text); font-size: .82rem; line-height: 1.6; }
.convoy-notice .terms { margin: 0; }

/* THE DISPATCHER'S PRICE, on the page reached from the request mail. The
   field stands above the two decisions rather than beside them: it belongs to
   "confirm", and "decline" needs nothing from it. */
.operator-quote { max-width: 22rem; margin-top: 1.5rem; }
.operator-quote .manage-actions { margin-top: 1rem; }
.field-error { margin: .4rem 0 0; color: #ffb4b4; font-size: .78rem; }

/* A CAR'S PAGE IS THE CAR'S COLOUR, ALL OF IT (Owner, 2026-09-24: "make every
   element on the page green"). Not a list of things to repaint - the site's
   own blue is two variables, and a car's page simply says they mean something
   else inside it. Everything that was blue because it read `--blue` follows on
   its own: the eyebrows, the price table's heads and figures, the links, the
   scrollbar, the focus rings, the form.

   `--blue-bright` is the lighter reading of the same colour and is mixed from
   it rather than listed a third time per tier - white at 22% turns the site's
   own blue into the exact bright it already used, so blue is unchanged and
   the other two get the same relationship.

   The header is outside this: it is the company's, not the car's. The footer
   joined it on 2026-09-26 (Owner: the Contact button under the red Luxury
   picture was still blue) - a car's page carries its class on the footer as
   well, and the footer's eyebrows, icons and button follow the car. */
.vehicle-page--standard, .vehicle-page--premium, .vehicle-page--luxury {
    --blue: var(--tier-mid);
    --blue-bright: color-mix(in srgb, var(--tier-mid) 78%, white);
}

/* THE FORM TAKES THE COLOUR OF THE CAR IT BOOKS (Owner, 2026-09-24: "if I
   order the green car from its own page, the order form is green"). The car's
   page already declares its colour - `--tier-mid` and `--tier-core`, the same
   pair the cards and their buttons read - so the form only has to stop
   spelling the site's blue out by hand.

   Scoped to the panel, because that is what carries the tokens, and every
   value falls back to the blue it was - so the same form on the front page,
   where no car has been chosen yet, is unchanged. */
.booking-panel {
    --form-accent: var(--tier-mid, var(--blue));
    --form-accent-bright: var(--tier-core, var(--blue-bright));
    /* The bright a car's page calls --blue-bright, for the panel's buttons. */
    --form-accent-light: color-mix(in srgb, var(--form-accent) 78%, white);
}
.booking-panel .quote {
    border-color: color-mix(in srgb, var(--form-accent) 27%, transparent);
    background: color-mix(in srgb, var(--form-accent) 7%, transparent);
}
.booking-panel .quote strong { color: var(--form-accent-bright); }
.booking-panel [data-total-leg] > span, .booking-panel [data-total-leg] > strong {
    border-top-color: color-mix(in srgb, var(--form-accent) 22%, transparent);
}
.booking-panel input:focus, .booking-panel select:focus, .booking-panel textarea:focus {
    border-color: var(--form-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--form-accent) 14%, transparent);
}
.booking-panel .return-toggle input,
.booking-panel .terms input,
.booking-panel .own-route-toggle input { accent-color: var(--form-accent); }
.booking-panel .eyebrow span { background: var(--form-accent); }
/* The same bright the footer's Contact button reads (--blue-bright on a car's
   page is exactly this mix), so the two buttons on one page are one style. */
.booking-panel .button, .booking-panel .submit {
    border-color: color-mix(in srgb, var(--form-accent-light) 48%, transparent);
    color: var(--form-accent-light);
}
.booking-panel .button:focus-visible, .booking-panel .submit:focus-visible {
    outline-color: var(--form-accent-light);
}
.booking-panel .suggest-list li.is-active,
.booking-panel .suggest-list li:hover { background: color-mix(in srgb, var(--form-accent) 18%, transparent); }

/* THE BOOKING PANEL'S EXTRA ROWS - the way back, and the two added up.
   `display: contents` so their parts fall into `.quote`'s own grid rather
   than making a box inside it; hidden they are gone, which the rule has to
   say, because display:contents would otherwise beat the browser's [hidden].
   The total is set apart by a hairline, the way a receipt sets one. */
.quote-leg { display: contents; }
.quote-leg[hidden] { display: none; }
.quote [data-total-leg] > span, .quote [data-total-leg] > strong {
    padding-top: .6rem;
    border-top: 1px solid color-mix(in srgb, var(--blue-bright) 22%, transparent);
}

/* THE RETURN'S OWN ROW. `display: contents` so its three parts fall into the
   panel's grid beside the outbound's, rather than making a box of their own
   (Owner, 2026-09-23: the price is split in two the moment a way back is
   asked for). Hidden it is gone entirely, which is why the rule has to say
   so - `display: contents` would otherwise beat the browser's own [hidden]. */
.route-estimate__leg { display: contents; }
.route-estimate__leg[hidden] { display: none; }

/* BEFORE THERE IS A PRICE THERE IS NO SECOND COLUMN (Owner, 2026-09-23:
   "what is going on with the alignment here?"). The two columns exist to put
   the figure beside the words "estimated price"; the sentence underneath then
   lines up with the figure it explains. With no figure yet, that sentence was
   still indented to a column holding nothing, hanging out to the right of an
   empty space while the line below it started at the edge. Empty, the panel
   is one column and everything starts at the same edge; the moment route-map.js
   has an amount it marks the block and the two columns come back. */
.route-map-block:not(.has-estimate) .route-estimate { grid-template-columns: 1fr; }
.route-map-block:not(.has-estimate) .route-estimate__amount { display: none; }
.route-map-block:not(.has-estimate) .route-estimate__meta { grid-column: 1; }
@media (max-width: 620px) {
    .route-estimate { grid-template-columns: 1fr; }
    .route-estimate__amount, .route-estimate__meta { grid-column: 1; }
}

/* SOME BUTTONS CARRY A PICTURE (Owner: the map on "Egen rute" 2026-09-19,
   the car on "Bestill tur" and the route line on "Se hvordan det virker"
   2026-09-23 - the Owner names each file after the button it belongs to).
   They stay buttons like any other: same classes as every `.button`, so the
   box model, the border, the sweep and the lift on hover are `.button` itself
   and nothing here touches them. The art is only a background under a dark
   scrim that keeps the text readable.

   ONE THING DOES have to be repeated: `.button:hover` sets its own
   `background` shorthand (the blue tint brightening), which is the IMAGE
   sub-property too, so on hover it was wiping the picture out from under the
   text (Owner, 2026-09-21: "the picture should stay no matter the effect").
   The fix is the same tint at the same moment, stacked over the picture
   instead of replacing it - the brightening still happens, the picture just
   survives it. Which picture is a custom property, so the scrim is written
   once and each button only names its own art. */
.button-art {
    background-image: linear-gradient(135deg,
                          color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 17%, transparent),
                          color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 5%, transparent)),
                      linear-gradient(rgb(7 11 18 / 55%), rgb(7 11 18 / 55%)),
                      var(--button-art);
    background-size: cover;
    background-position: center;
}
.button-art--map { --button-art: url("../images/route-button.b2226ceba0cc.png"); }
.button-art--ride { --button-art: url("../images/book-a-ride.5cd50fee0d88.webp"); }
.button-art--works { --button-art: url("../images/how-it-works.1c1123d74d98.webp"); }
.button-art--send { --button-art: url("../images/send-request.c9f8dfb8294f.webp"); }
.button-art--contact { --button-art: url("../images/contact.6f631efc35d5.webp"); }
/* The front page's Contact, quieter against the footer-1 dusk (Owner,
   2026-09-26, variant C of three shown on the live page). */
/* White label on every footer's Contact (Owner, 2026-09-26) - the frame and
   the picture carry the page's colour, the word stays white on all of them.
   Written against .site-footer to outrank ledo.css `.footer-maker a`. */
.site-footer .footer-cta { color: #fff; }
/* ...and the same white on every Send button (Owner, 2026-09-26: "тоже
   белой"), so the two buttons on a page are one style. After the booking
   panel's rule, which colours the panel's other buttons by the car. */
.submit.button-art--send { color: #fff; }
.footer--quiet .footer-cta { border-color: rgb(120 150 200 / 45%); background-color: rgb(14 24 44 / 70%); background-image: linear-gradient(rgb(10 18 34 / 62%), rgb(10 18 34 / 62%)), var(--button-art); }
/* The button art in the red and green cars' colour: the Owner's own blue
   pictures with only their hue turned (Owner, 2026-09-26: the Contact button
   under the Luxury picture must be red, and every button on a car's page is
   to look the same). Premium is blue already. */
.vehicle-page--luxury .button-art--contact { --button-art: url("../images/contact-luxury.1c13a1431f6d.webp"); }
.vehicle-page--standard .button-art--contact { --button-art: url("../images/contact-standard.61a66aa7fe04.webp"); }
.vehicle-page--luxury .button-art--send { --button-art: url("../images/send-request-luxury.58087e5b5340.webp"); }
.vehicle-page--standard .button-art--send { --button-art: url("../images/send-request-standard.ca6b6b9cc41d.webp"); }
.button-art--standard { --button-art: url("../images/fleet-standard.5025fc56daa0.webp"); }
.button-art--premium { --button-art: url("../images/fleet-premium.97a391b5f498.webp"); }
.button-art--luxury { --button-art: url("../images/fleet-luxury.0e912a87065e.webp"); }

/* THE ADDRESS SUGGESTIONS (address-suggest.js). Our own list, not a browser
   datalist, because a datalist hides every option that does not contain what
   was typed and "airport" is never inside "Oslo lufthavn" (Owner,
   2026-09-23). It hangs from the field, which the script makes its
   containing block, and it wears the panel's own night and rim so it reads
   as part of the form rather than as a browser widget. */
.suggest-list {
    position: absolute;
    top: calc(100% + .3rem);
    right: 0;
    left: 0;
    z-index: 30;
    max-height: 15rem;
    margin: 0;
    padding: .25rem;
    overflow-y: auto;
    list-style: none;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 38%, transparent);
    border-radius: .4rem;
    background: rgb(9 15 25 / 97%);
    box-shadow: 0 1rem 2rem rgb(0 0 0 / 45%);
}
.suggest-list li {
    padding: .5rem .6rem;
    border-radius: .3rem;
    color: var(--ice);
    font-size: .8rem;
    line-height: 1.4;
    cursor: pointer;
}
.suggest-list li.is-active, .suggest-list li:hover { background: color-mix(in srgb, var(--blue) 18%, transparent); }

/* "USE MY LOCATION" - a target icon inside the pick-up field (Owner,
   2026-10-06, option A), so the form's rows keep their line. */
.locate-wrap { position: relative; }
.locate-wrap input { padding-right: 3rem; }
.locate-wrap .locate-button {
    position: absolute;
    top: 50%;
    right: .375rem;
    display: grid;
    place-items: center;
    width: 2.25rem;
    min-height: 0;
    height: 2.25rem;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 35%, transparent);
    border-radius: .5rem;
    background: color-mix(in srgb, var(--blue) 15%, transparent);
    box-shadow: none;
    color: var(--blue-bright);
    transform: translateY(-50%);
    cursor: pointer;
}
.locate-wrap .locate-button:hover { background: color-mix(in srgb, var(--blue) 30%, transparent); }
.locate-wrap .locate-button.is-busy svg { animation: locate-pulse 1s ease-in-out infinite; }
.locate-wrap .locate-button.is-failed { border-color: #c0605a; color: #ff9b94; }
@keyframes locate-pulse { 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .locate-wrap .locate-button.is-busy svg { animation: none; opacity: .5; } }

/* EVERY LABEL IS CENTRED, on every button, on the phone and on the desktop
   alike (Owner, 2026-09-24). They were pushed to the right for a while, so
   the pictures would not be covered - but buttons stand under one another in
   a column, and a label that is centred on one and hard right on the next
   reads as a mistake. The picture goes under the word; the scrim over it is
   what keeps the word readable. */
@media (hover: hover) {
    .button-art:hover {
        background-image: linear-gradient(135deg,
                              color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 30%, transparent),
                              color-mix(in srgb, var(--tier-mid, rgb(85 167 255)) 10%, transparent)),
                          linear-gradient(rgb(7 11 18 / 55%), rgb(7 11 18 / 55%)),
                          var(--button-art);
        background-size: cover;
        background-position: center;
    }
}

/* FULL SCREEN WHEN THE PHONE IS TURNED (Owner, 2026-09-20). The map leaves
   its card and takes the screen; the rest of the page waits underneath. The
   rotate button shows only on a phone held upright; the cross only in full
   screen. Same night, same blue rim as the map's other controls. */
html.route-map-full .route-map {
    position: fixed; inset: 0; width: 100vw; height: 100dvh; z-index: 9999;
    border-radius: 0; border: 0;
}
html.route-map-full body { overflow: hidden; }
/* The card the map sits in is lifted by a transform (and brightened on
   hover); either makes it the containing block of a fixed child, and the
   map would fill the card, not the screen. Off while the map is out. */
html.route-map-full .tier-card, html.route-map-full .tier-card:hover { transform: none; filter: none; }
html.route-map-full .site-header, html.route-map-full .site-footer,
html.route-map-full .route-map-block > :not(.route-map) { visibility: hidden; }
.route-map__rotate, .route-map__close {
    position: absolute; z-index: 5; display: none; align-items: center; justify-content: center;
    width: 2.4rem; height: 2.4rem; padding: 0; border-radius: 50%;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 45%, transparent); background: rgb(7 11 18 / 85%); color: var(--ice);
    box-shadow: 0 0 12px color-mix(in srgb, var(--blue) 25%, transparent); cursor: pointer;
}
.route-map__rotate { left: .6rem; top: .6rem; }
.route-map__close { left: .6rem; top: .6rem; font-size: 1rem; line-height: 1; }   /* the zoom buttons own the right corner */
@media (orientation: portrait) and (pointer: coarse) { .route-map__rotate { display: flex; } }
html.route-map-full .route-map__close { display: flex; }
html.route-map-full .route-map__rotate { display: none; }
.route-map__hint {
    position: fixed; inset: 0; z-index: 10000; display: grid; place-content: center; gap: 1rem;
    padding: 2rem; text-align: center; color: var(--ice);
    background: rgb(7 11 18 / 92%); cursor: pointer;
}
.route-map__hint p { margin: 0; max-width: 18rem; font-size: 1.05rem; line-height: 1.4; }
.route-map__phone { justify-self: center; color: var(--blue-bright); animation: route-map-turn 2.4s ease-in-out infinite; }
@keyframes route-map-turn { 0%, 20% { transform: rotate(0); } 55%, 80% { transform: rotate(-90deg); } 100% { transform: rotate(0); } }
@media (prefers-reduced-motion: reduce) {
    .route-map { transition: none; }
    .route-map__phone { animation: none; transform: rotate(-90deg); }
}

/* UP TO TWO STOPS BETWEEN ORIGIN AND DESTINATION (Owner and Violeta,
   2026-09-21: "up to four points on the route"). A stop's pin reads as a
   waypoint, not an endpoint - the same glow, a dimmer fill so the eye still
   finds A and the last point first. The "×" sits on the field's own row,
   away from the text so it is never mistaken for part of the address. */
.route-pin--stop { background: #1d4f86; border-color: #9fd4ff; }
.route-stop-row { position: relative; }
.route-stop-remove {
    position: absolute; top: 0; right: 0;
    width: 1.6rem; height: 1.6rem; padding: 0; border: 0; background: none;
    color: var(--muted); font-size: .85rem; line-height: 1; cursor: pointer;
}
.route-stop-remove:hover, .route-stop-remove:focus-visible { color: var(--ice); }
.route-add-stop-row { margin-top: -.3rem; }
.route-add-stop-row .button { width: auto; min-height: 2.2rem; padding: .4rem .9rem; font-size: .72rem; }

/* THE JOURNEY CARD (Owner, 2026-09-25: "very ugly, nowhere near Premium").
   The receipt, the booking's own page and the own-route request's page drew
   their facts as a bare centred column. One card now, built like the map
   draws a road: a pin where it starts, a pin where it ends, a glowing line
   between, the hour beside each. Every colour reads --blue, so on a car's
   colour (the page's main carries vehicle-page--*) the card is that car's. */
.journey-ticket {
    position: relative; overflow: hidden;
    width: min(100%, 40rem); margin: 2.4rem auto; text-align: left;
    border: 1px solid color-mix(in srgb, var(--blue) 32%, transparent);
    border-radius: 1.25rem;
    background:
        radial-gradient(120% 70% at 0% 0%, color-mix(in srgb, var(--blue) 14%, transparent), transparent 60%),
        linear-gradient(165deg, var(--panel), var(--night-soft) 75%);
    box-shadow: 0 1.8rem 3.6rem rgb(0 0 0 / 38%), 0 0 2.6rem color-mix(in srgb, var(--blue) 12%, transparent);
}
.journey-ticket::before {
    content: ""; position: absolute; inset: 0 0 auto; height: 2px;
    background: linear-gradient(90deg, transparent, var(--blue-bright), transparent);
}
/* The status is the head's only content, so it stands in the middle of the
   card (Owner, 2026-11-05), not against its left edge. */
.journey-ticket__head {
    display: flex; align-items: center; justify-content: center; gap: 1rem;
    padding: 1.1rem 1.5rem; border-bottom: 1px solid var(--line);
}
.journey-ticket__status {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .38rem .85rem; border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--blue) 45%, transparent);
    background: color-mix(in srgb, var(--blue) 10%, transparent);
    color: var(--blue-bright); font-size: .7rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.journey-ticket__status::before {
    content: ""; width: .45rem; height: .45rem; border-radius: 50%;
    background: currentColor; box-shadow: 0 0 .6rem currentColor;
}
.journey-ticket--wait .journey-ticket__status::before { animation: journey-pulse 1.8s ease-in-out infinite; }
@keyframes journey-pulse { 50% { opacity: .35; box-shadow: 0 0 0 currentColor; } }

.journey-ticket__road { margin: 0; padding: 1.7rem 1.5rem .4rem; list-style: none; }
.journey-ticket__point {
    position: relative; display: grid; grid-template-columns: 1.75rem 1fr auto; column-gap: .9rem; align-items: baseline;
    padding-bottom: 1.5rem;
}
.journey-ticket__point > small { grid-column: 2; color: var(--muted); font-size: .66rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.journey-ticket__point > strong { grid-column: 2; font-size: 1.3rem; font-weight: 650; letter-spacing: -.01em; line-height: 1.25; overflow-wrap: anywhere; }
.journey-ticket__point > time { grid-column: 3; grid-row: 1 / span 2; align-self: center; text-align: right; color: var(--muted); font-size: .78rem; white-space: nowrap; }
.journey-ticket__point > time b { display: block; color: var(--blue-bright); font-size: 1.35rem; font-weight: 700; letter-spacing: -.01em; }
.journey-ticket__sep { display: none; }
/* The pin - the map's own, so the card and the map are one drawing. */
.journey-ticket__point::before {
    content: ""; position: absolute; left: .3rem; top: .95rem; z-index: 1;
    width: .75rem; height: .75rem; border-radius: 50%;
    background: var(--ice); border: 3px solid var(--blue);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--blue) 22%, transparent), 0 0 1rem color-mix(in srgb, var(--blue) 80%, transparent);
}
.journey-ticket__point--destination::before { background: var(--blue); border-color: var(--ice); }
.journey-ticket__point--stop::before { left: .45rem; width: .45rem; height: .45rem; border-width: 2px; }
.journey-ticket__point--return::before { background: transparent; border-style: dashed; box-shadow: none; }
/* The road between one pin and the next. */
.journey-ticket__point:not(:last-child)::after {
    content: ""; position: absolute; left: calc(.3rem + .375rem + 2px); top: 1.9rem; bottom: .1rem; width: 2px;
    transform: translateX(-50%);
    background: linear-gradient(var(--blue), var(--blue-bright));
    box-shadow: 0 0 .6rem color-mix(in srgb, var(--blue) 70%, transparent);
}
/* The way back is another journey, so its line is drawn broken. */
.journey-ticket__point--destination:not(:last-child)::after {
    background: repeating-linear-gradient(var(--muted) 0 .3rem, transparent .3rem .6rem); box-shadow: none;
}

/* THE url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9.2 4.3 5.5a1.5 1.5 0 0 1 1.4-1h4.6a1.5 1.5 0 0 1 1.4 1L13 9.2'/%3E%3Crect x='2.2' y='9.2' width='11.6' height='3.4' rx='1.2'/%3E%3Cpath d='M4 12.6V14M12 12.6V14'/%3E%3Ccircle cx='4.9' cy='10.9' r='.45'/%3E%3Ccircle cx='11.1' cy='10.9' r='.45'/%3E%3C/svg%3E"), THE url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='6.2' cy='5.4' r='2.3'/%3E%3Cpath d='M1.9 13.6c.4-2.6 2.1-4.2 4.3-4.2s3.9 1.6 4.3 4.2'/%3E%3Cpath d='M10.4 3.3a2.2 2.2 0 1 1 0 4.3M11.6 9.6c1.4.4 2.3 1.8 2.6 4'/%3E%3C/svg%3E"), THE url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2.6' y='5' width='10.8' height='8.4' rx='1.4'/%3E%3Cpath d='M6 5V3.6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1V5M5.4 5v8.4M10.6 5v8.4'/%3E%3C/svg%3E")S AND THE PRICE AS TILES (Owner, 2026-11-05:
   "a random caption and a number scattered over a table"). Every tile is
   centred: the footer's blue line icon, the figure, and its caption under
   it; the tiles of a row share their lines (subgrid), so the figures stand
   level even where one caption runs to two lines. The price is the same
   tile, its figure in the board's glowing blue. */
.journey-ticket__facts {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(3, auto); margin: 0;
    border-block: 1px solid var(--line);
}
.journey-ticket__facts div { display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: .4rem; justify-items: center; align-items: start; padding: 1.1rem .75rem 1.2rem; text-align: center; }
.journey-ticket__facts div + div { border-left: 1px solid var(--line); }
.journey-ticket__facts div::before { content: ""; width: 1.35rem; height: 1.35rem; background: var(--blue); -webkit-mask: var(--fact-icon) center / contain no-repeat; mask: var(--fact-icon) center / contain no-repeat; }
.journey-ticket__facts div:nth-child(1) { --fact-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9.2 4.3 5.5a1.5 1.5 0 0 1 1.4-1h4.6a1.5 1.5 0 0 1 1.4 1L13 9.2'/%3E%3Crect x='2.2' y='9.2' width='11.6' height='3.4' rx='1.2'/%3E%3Cpath d='M4 12.6V14M12 12.6V14'/%3E%3Ccircle cx='4.9' cy='10.9' r='.45'/%3E%3Ccircle cx='11.1' cy='10.9' r='.45'/%3E%3C/svg%3E"); }
.journey-ticket__facts div:nth-child(2) { --fact-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='6.2' cy='5.4' r='2.3'/%3E%3Cpath d='M1.9 13.6c.4-2.6 2.1-4.2 4.3-4.2s3.9 1.6 4.3 4.2'/%3E%3Cpath d='M10.4 3.3a2.2 2.2 0 1 1 0 4.3M11.6 9.6c1.4.4 2.3 1.8 2.6 4'/%3E%3C/svg%3E"); }
.journey-ticket__facts div:nth-child(3) { --fact-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2.6' y='5' width='10.8' height='8.4' rx='1.4'/%3E%3Cpath d='M6 5V3.6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1V5M5.4 5v8.4M10.6 5v8.4'/%3E%3C/svg%3E"); }
.journey-ticket__facts dd, .journey-ticket__prices dd { order: 1; margin: 0; font-size: 1.2rem; font-weight: 650; line-height: 1.2; white-space: nowrap; }
.journey-ticket__facts dt, .journey-ticket__prices dt { order: 2; color: var(--muted); font-size: .62rem; font-weight: 600; letter-spacing: .14em; line-height: 1.45; text-transform: uppercase; }

.journey-ticket__prices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; }
.journey-ticket__prices div { display: grid; align-content: start; justify-items: center; gap: .4rem; padding: 1.1rem .75rem 1.2rem; text-align: center; border-bottom: 1px solid var(--line); }
.journey-ticket__prices div:nth-child(2):not(.is-total) { border-left: 1px solid var(--line); }
.journey-ticket__prices dt small { display: block; margin-top: .25rem; color: var(--blue-bright); font-size: .68rem; font-weight: 500; letter-spacing: .04em; text-transform: none; }
.journey-ticket__prices .is-total { grid-column: 1 / -1; padding: 1.3rem 1.5rem 1.4rem; border-bottom: 0; }
.journey-ticket__prices .is-total dd { color: var(--blue-bright); font-size: 2rem; letter-spacing: -.02em; text-shadow: 0 0 1.2rem color-mix(in srgb, var(--blue) 45%, transparent); }

.journey-ticket__ref {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .7rem;
    padding: .85rem 1.5rem; background: rgb(0 0 0 / 22%);
}
.journey-ticket__ref small { color: var(--muted); font-size: .64rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.journey-ticket__ref code { color: var(--muted); font-size: .76rem; overflow-wrap: anywhere; }

/* A journey that will not happen is a record: the colour goes out of it. */
.journey-ticket--off { border-color: var(--line); box-shadow: 0 1.8rem 3.6rem rgb(0 0 0 / 38%); }
.journey-ticket--off .journey-ticket__status { border-color: var(--line); background: transparent; color: var(--muted); }
.journey-ticket--off .journey-ticket__status::before { box-shadow: none; }
.journey-ticket--off .journey-ticket__road, .journey-ticket--off .journey-ticket__prices { filter: grayscale(1); opacity: .7; }

@media (max-width: 560px) {
    .journey-ticket { border-radius: 1rem; }
    .journey-ticket__head, .journey-ticket__ref { padding-inline: 1.1rem; }
    .journey-ticket__road { padding-inline: 1.1rem; }
    .journey-ticket__point { grid-template-columns: 1.75rem 1fr; }
    .journey-ticket__point > time { grid-column: 2; grid-row: auto; text-align: left; margin-top: .35rem; }
    .journey-ticket__point > time b { display: inline; font-size: 1.05rem; }
    .journey-ticket__sep { display: inline; }
    .journey-ticket__facts div, .journey-ticket__prices div:not(.is-total) { padding: 1rem .5rem 1.1rem; }
}
@media (prefers-reduced-motion: reduce) { .journey-ticket--wait .journey-ticket__status::before { animation: none; } }

/* "My journeys" draws each journey ahead as the journey card (Owner,
   2026-09-25), in its own car's colour, with its buttons on the card. */
.journey-tickets { display: grid; gap: 1.6rem; margin: 1rem 0 2.4rem; }
.journey-tickets .journey-ticket { margin: 0 auto; }
.journey-ticket__actions {
    display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem;
    padding: 1rem 1.5rem 1.2rem; border-top: 1px solid var(--line);
}
.journey-ticket__actions form { margin: 0; }
.journey-ticket__actions .button { min-height: 2.75rem; padding-inline: 1.2rem; }

/* SIGHTSEEING (Owner and Violeta, 2026-10-10/12): a catalogue of sights on
   the left, the tour planner beside it - the map, the plan, the price and the
   form - held in view while the visitor scrolls the list. One column on a
   phone, the planner under the list. */
.sights-hero { max-width: var(--page-width); margin-inline: auto; padding: 3rem calc(var(--gutter) + var(--text-inset)) 1rem; }
.sights-hero h1 { margin: .4rem 0 .8rem; font-size: clamp(2rem, 4.6vw, 3.4rem); line-height: 1.05; }
.sights-hero p { max-width: 46rem; color: var(--muted, #b9c6d6); }
.sights-layout { max-width: var(--page-width); margin: 0 auto 3rem; padding: 0 calc(var(--gutter) + var(--text-inset));
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(20rem, 26rem); gap: 1.5rem; align-items: start; }
.sights-errors { grid-column: 1 / -1; }
.sights-filter { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
.sights-chip { padding: .45rem .9rem; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--blue-bright) 30%, transparent);
    background: transparent; color: var(--ice); font: inherit; font-size: .82rem; cursor: pointer; }
.sights-chip.is-active, .sights-chip:hover { background: color-mix(in srgb, var(--blue) 22%, transparent); border-color: var(--blue-bright); }
/* Each region's heading wears the site's own eyebrow - the blue stroke, then
   the name - and a hairline that runs on to the grid's right edge (Owner,
   2026-10-12: "it was lost on the left"). */
.sights-region { margin-top: 2.2rem; }
.sights-region:first-of-type { margin-top: .6rem; }
.sights-region h2 { display: flex; align-items: center; gap: .9rem; margin: 0 0 1.1rem; color: var(--ice, #e9f2fb);
    font-size: 1.05rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.sights-region h2::before { content: ""; width: 2.4rem; height: 2px; flex: none; background: var(--blue-bright); }
.sights-region h2::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.sights-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1rem; }
.sight-card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: .7rem; overflow: hidden;
    background: linear-gradient(150deg, var(--panel), var(--night-soft)); transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease; }
/* The form card's own hover (Owner, 2026-10-12: "the same effect as the form
   on the right") - `.tier-card` - with its firefly lit only under the cursor
   or once picked, so a page of thirty cards does not all glitter at once. */
.sight-card.tier-card { transform: none; }
.sight-card.tier-card::after { opacity: 0; transition: opacity .25s; }
.sight-card.tier-card.is-picked::after { opacity: .72; }
@media (hover: hover) { .sight-card.tier-card:hover { transform: translateY(-4px); } }
.sight-card.is-picked { border-color: var(--blue-bright); box-shadow: 0 0 0 1px var(--blue-bright), 0 0 24px color-mix(in srgb, var(--blue) 30%, transparent); }
.sight-card__photo { position: relative; margin: 0; aspect-ratio: 4 / 3; background: #070b12; }
.sight-card__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sight-card__photo figcaption { position: absolute; right: 0; bottom: 0; max-width: 100%; padding: .15rem .45rem; font-size: .6rem;
    color: rgb(230 240 250 / 85%); background: rgb(7 11 18 / 62%); border-top-left-radius: .35rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sight-card__photo figcaption a { color: inherit; }
.sight-card__body { display: flex; flex-direction: column; gap: .45rem; padding: .9rem 1rem 1rem; flex: 1; }
.sight-card__body h3 { margin: 0; font-size: 1rem; line-height: 1.25; }
.sight-card__body .sight-card__town { flex: none; display: flex; align-items: center; gap: .35rem; color: var(--blue-bright); font-size: .78rem; font-weight: 600; }
.sight-card__town::before { content: ""; width: .75rem; height: .75rem; flex: none; background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a7 7 0 0 0-7 7c0 5 7 13 7 13s7-8 7-13a7 7 0 0 0-7-7zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a7 7 0 0 0-7 7c0 5 7 13 7 13s7-8 7-13a7 7 0 0 0-7-7zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E") center / contain no-repeat; }
.sight-card__body p { margin: 0; font-size: .82rem; line-height: 1.5; color: var(--muted, #b9c6d6); flex: 1; }
.sight-card__foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: .4rem; }
.sight-card__pick { display: inline-flex; align-items: center; gap: .45rem; font-size: .85rem; font-weight: 600; cursor: pointer; }
.sight-card__pick input { flex: none; width: 1.15rem; height: 1.15rem; min-height: 0; margin: 0; padding: 0; border: 0; background: none; box-shadow: none; accent-color: var(--blue-bright); }
.sight-card__stay { display: inline-flex; align-items: center; gap: .3rem; font-size: .75rem; color: var(--muted, #b9c6d6); }
.sight-card__stay input { width: 4.2rem; min-height: 0; padding: .25rem .4rem; font-size: .8rem; text-align: right; }
.sights-planner { position: sticky; top: 1rem; display: grid; gap: 1rem; padding: 1.25rem; border-radius: .8rem;
    max-height: calc(100vh - 2rem); overflow-y: auto; }
.sights-planner h2 { margin: 0; font-size: 1.2rem; }
.sights-planner fieldset { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin: 0; padding: 0; border: 0; }
.sights-planner .field.full { grid-column: 1 / -1; }
.sights-map { height: 15rem; }
.sights-plan { margin: 0; padding: 0; list-style: none; display: grid; gap: .35rem; font-size: .82rem; }
.sights-plan:empty { display: none; }
.sights-plan li { display: grid; grid-template-columns: 6.6rem 1fr; column-gap: .6rem; }
.sights-plan time { color: var(--blue-bright); font-variant-numeric: tabular-nums; }
.sights-plan small { grid-column: 2; color: var(--muted, #b9c6d6); font-size: .72rem; }
.sights-jump { display: none; }
@media (min-width: 1101px) { .nav-links .nav-burger-only { display: none; } }
@media (max-width: 960px) {
    .sights-layout { grid-template-columns: 1fr; }
    /* Above the Help button, which owns the bottom corner. */
    .sights-jump:not([hidden]) { position: fixed; z-index: 40; left: 50%; bottom: calc(max(1rem, env(safe-area-inset-bottom)) + 4.2rem); transform: translateX(-50%);
        display: inline-flex; gap: .35rem; padding: .8rem 1.4rem; border-radius: 999px; white-space: nowrap; font-weight: 600; color: #fff; text-decoration: none;
        background: linear-gradient(135deg, rgb(22 48 75 / 96%), rgb(8 15 25 / 96%)); border: 1px solid var(--blue-bright);
        box-shadow: 0 .6rem 1.6rem rgb(0 0 0 / 55%), 0 0 18px color-mix(in srgb, var(--blue) 35%, transparent); }
    .sights-planner { position: static; max-height: none; overflow: visible; }
}
@media (max-width: 480px) {
    .sights-grid { grid-template-columns: 1fr; }
    .sights-planner fieldset { grid-template-columns: 1fr; }
}


/* THE SITE'S OWN CALENDAR (calendar.js; Owner and Violeta, 2026-10-12: the
   phone's own picker spoke the phone's language on every page). The native
   field stays in the form, out of sight; the button and the panel wear the
   form's own night, rim and blue. */
.cal-field { position: relative; }
.cal-native { position: absolute !important; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
.cal-trigger { display: flex; align-items: center; justify-content: space-between; gap: .75rem; width: 100%; min-height: 3rem;
    padding: .7rem 1rem; border: 1px solid var(--line); border-radius: .4rem; background: var(--night, #070b12);
    color: var(--ice, #e9f2fb); font: inherit; text-align: left; cursor: pointer; }
.cal-trigger:hover, .cal-trigger:focus-visible { border-color: var(--blue-bright); }
.cal-trigger.is-empty .cal-trigger__text { color: var(--muted); }
.cal-trigger svg { flex: none; color: var(--blue-bright); }
.cal-panel { position: absolute; z-index: 9500; width: 21rem; max-width: calc(100vw - 2rem);
    display: grid; gap: .8rem; padding: 1rem; border-radius: .7rem;
    border: 1px solid color-mix(in srgb, var(--blue-bright) 45%, transparent);
    background: linear-gradient(150deg, var(--panel), var(--night-soft)); box-shadow: 0 1.2rem 2.4rem rgb(0 0 0 / 55%); }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.cal-title { font-size: .95rem; }
.cal-nav { flex: none; width: 2.2rem; height: 2.2rem; padding: 0; border: 1px solid var(--line); border-radius: .4rem;
    background: transparent; color: var(--ice, #e9f2fb); font-size: 1.2rem; line-height: 1; cursor: pointer; }
.cal-nav:disabled { opacity: .3; cursor: default; }
.cal-panel :where(button, select) { min-width: 0; min-height: 0; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .2rem; text-align: center; }
.cal-weekday { font-size: .68rem; color: var(--muted); padding-bottom: .2rem; }
.cal-day { width: auto; aspect-ratio: 1; padding: 0; border: 1px solid transparent; border-radius: .4rem;
    background: transparent; color: var(--ice, #e9f2fb); font: inherit; font-size: .85rem; cursor: pointer; }
.cal-day:hover:not(:disabled) { background: color-mix(in srgb, var(--blue) 22%, transparent); }
.cal-day.is-today { border-color: color-mix(in srgb, var(--blue-bright) 55%, transparent); }
.cal-day.is-chosen { background: var(--blue-bright); color: var(--night, #070b12); font-weight: 700; }
.cal-day:disabled { opacity: .25; cursor: default; }
.cal-time { display: flex; align-items: center; gap: .4rem; }
.cal-time__label { margin-right: auto; font-size: .85rem; color: var(--muted); }
.cal-select { width: 4.5rem; padding: .45rem .5rem; font-size: .95rem; }
.cal-actions { display: flex; justify-content: flex-end; gap: .5rem; }
.cal-actions .button { width: auto; padding: .55rem 1rem; }
@media (max-width: 480px) {
    .cal-panel { position: fixed; top: auto; left: .75rem; right: .75rem; bottom: max(.75rem, env(safe-area-inset-bottom)); width: auto; max-width: none;
        box-shadow: 0 0 0 100vmax rgb(0 0 0 / 60%), 0 1.2rem 2.4rem rgb(0 0 0 / 55%); }
}


/* THE HELP CHAT (chat.js; Owner and Violeta, 2026-10-12). The button sits in
   the corner of every page and lifts above the install banner while that is
   shown; the window is the form's own night and rim, a sheet on a phone. */
.hc-fab { position: fixed; right: 20px; bottom: 20px; z-index: 9200; display: flex; align-items: center; gap: 10px;
    padding: 12px 18px 12px 14px; border-radius: 999px; border: 1px solid var(--blue-bright);
    background: linear-gradient(135deg, rgb(22 48 75 / 96%), rgb(8 15 25 / 96%)); color: #fff; font: 600 15px "Segoe UI", system-ui, sans-serif;
    box-shadow: 0 10px 26px rgb(0 0 0 / 55%), 0 0 18px color-mix(in srgb, var(--blue) 35%, transparent); cursor: pointer; }
.hc-fab[hidden] { display: none; }
.hc-fab svg { color: var(--blue-bright); }
body:has(#pwa-install-banner:not([hidden])) .hc-fab { bottom: 96px; }
.hc-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 8px #4ade80; }
.hc-dot.off { background: #94a3b8; box-shadow: none; }
.hc-fab .hc-dot { display: none; }
.hc-fab .hc-dot:not(.off) { display: inline-block; }
.hc-panel { position: fixed; right: 20px; bottom: 20px; z-index: 9300; width: 370px; max-height: min(620px, calc(100vh - 40px));
    display: flex; flex-direction: column; border-radius: 16px; border: 1px solid color-mix(in srgb, var(--blue-bright) 45%, transparent);
    background: linear-gradient(150deg, var(--panel), var(--night-soft)); color: var(--ice, #e9f2fb);
    box-shadow: 0 22px 50px rgb(0 0 0 / 60%); font: 14px/1.45 "Segoe UI", system-ui, sans-serif; overflow: hidden; }
.hc-head { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--line);
    background: linear-gradient(135deg, color-mix(in srgb, var(--blue) 16%, transparent), transparent); }
.hc-head img { width: 50px; height: 50px; flex: none; margin: -4px 0; object-fit: contain; filter: drop-shadow(0 0 6px rgb(85 167 255 / 35%)); }
.hc-head b { display: block; font-size: 15px; }
.hc-head small { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; }
.hc-panel button { min-width: 0; min-height: 0; width: auto; }
.hc-x { margin-left: auto; padding: 4px 8px; background: none; border: 0; color: var(--muted); font-size: 20px; cursor: pointer; }
.hc-body { flex: 1; padding: 16px 18px; overflow: auto; display: grid; gap: 10px; align-content: start; }
.hc-hello { color: #c9d6e4; }
.hc-topics { display: grid; gap: 8px; }
.hc-topic { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; border-radius: 10px;
    border: 1px solid var(--line); background: rgb(255 255 255 / 3%); color: var(--ice, #e9f2fb); font: inherit; text-align: left; cursor: pointer; }
.hc-panel .hc-topic { width: 100%; }
.hc-topic:hover { border-color: var(--blue-bright); background: color-mix(in srgb, var(--blue) 14%, transparent); }
.hc-topic span { color: var(--blue-bright); }
.hc-msg { max-width: 82%; padding: 9px 12px; border-radius: 12px; font-size: 13.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
.hc-msg small { display: block; margin-top: 3px; font-size: 11px; color: var(--muted); }
.hc-me { justify-self: end; background: #2a6fb8; color: #fff; border-bottom-right-radius: 4px; }
.hc-me small { color: #d8e8fb; }
.hc-them { justify-self: start; background: rgb(255 255 255 / 7%); border-bottom-left-radius: 4px; }
.hc-chip { justify-self: center; font-size: 11.5px; color: var(--muted); padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; }
.hc-off { padding: 10px 12px; border-radius: 10px; background: rgb(148 163 184 / 10%); border: 1px solid rgb(148 163 184 / 25%); font-size: 13px; }
.hc-foot { padding: 12px 14px; border-top: 1px solid var(--line); display: grid; gap: 8px; }
.hc-row { display: flex; gap: 8px; }
.hc-in { flex: 1; min-width: 0; padding: 11px 12px; border-radius: 10px; border: 1px solid rgb(255 255 255 / 14%);
    background: #070b12; color: var(--ice, #e9f2fb); font: inherit; }
.hc-panel .hc-who .hc-in { min-height: 0; height: 2.3rem; padding: 6px 10px; font-size: 13px; }
.hc-text { resize: none; min-height: 4.6rem; line-height: 1.4; }
.hc-row:has(.hc-text) { align-items: stretch; }
.hc-send { padding: 0 16px; border-radius: 10px; border: 1px solid var(--blue-bright); background: #2a6fb8; color: #fff; font: 600 14px inherit; cursor: pointer; }
.hc-note, .hc-ask { font-size: 12px; color: var(--muted); }
.hc-note { text-align: center; }
.hc-ask p { margin: 0 0 6px; }
.hc-error { font-size: 12px; color: #ff9b94; }
.hc-error:empty { display: none; }
.hc-trap { position: absolute; left: -9999px; }
@media (max-width: 480px) {
    .hc-fab { right: 14px; bottom: 14px; }
    .hc-panel { left: 0; right: 0; bottom: 0; width: auto; max-height: 88vh; border-radius: 18px 18px 0 0;
        box-shadow: 0 0 0 100vmax rgb(0 0 0 / 55%); }
}

/* THE DISPATCHER'S INBOX (/chat/, staff only). */
.ib { max-width: var(--page-width); margin: 0 auto; padding: 2rem calc(var(--gutter) + var(--text-inset)) 3rem; }
.ib-top { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.2rem; }
.ib-top h1 { margin: 0; font-size: 2rem; }
.ib-duty { margin-left: auto; display: flex; align-items: center; gap: .7rem; padding: .55rem 1rem; border-radius: 999px;
    border: 1px solid var(--line); background: transparent; color: var(--ice, #e9f2fb); font: 600 14px inherit; cursor: pointer; }
.ib-duty i { width: 38px; height: 22px; border-radius: 999px; background: #475569; position: relative; transition: background .2s; }
.ib-duty i::after { content: ""; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .2s; }
.ib-duty.is-on { border-color: #4ade80; background: rgb(74 222 128 / 10%); }
.ib-duty.is-on i { background: #4ade80; }
.ib-duty.is-on i::after { left: 19px; }
.ib-grid { display: grid; grid-template-columns: 20rem 1fr; gap: 1rem; min-height: 34rem; }
.ib-list, .ib-thread { border: 1px solid var(--line); border-radius: .8rem; background: linear-gradient(150deg, var(--panel), var(--night-soft)); overflow: hidden; }
.ib-list { overflow-y: auto; max-height: 70vh; }
.ib-item { display: grid; gap: .15rem; width: 100%; padding: .85rem 1rem; border: 0; border-bottom: 1px solid rgb(255 255 255 / 7%);
    background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.ib-item.on { background: color-mix(in srgb, var(--blue) 14%, transparent); box-shadow: inset 3px 0 var(--blue-bright); }
.ib-item.is-closed { opacity: .55; }
.ib-item b { display: flex; justify-content: space-between; gap: .5rem; font-size: 14px; }
.ib-item b em { font-style: normal; font-weight: 400; color: var(--muted); font-size: 12px; }
.ib-item > span:last-child { color: var(--muted); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ib-tag { justify-self: start; font-size: 11px; padding: 1px 8px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--blue-bright) 40%, transparent); color: var(--blue-bright); }
.ib-new { width: 8px; height: 8px; border-radius: 50%; background: var(--blue-bright); display: inline-block; margin-right: 6px; }
.ib-thread { display: flex; flex-direction: column; }
.ib-th-head { padding: 1rem 1.2rem; border-bottom: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: .4rem 1rem; align-items: center; }
.ib-th-head small { color: var(--muted); }
.ib-th-head button { margin-left: auto; background: none; border: 0; color: var(--blue-bright); text-decoration: underline; font: inherit; font-size: 13px; cursor: pointer; width: auto; min-height: 0; }
.ib-msgs { flex: 1; padding: 1.2rem; display: grid; gap: .6rem; align-content: start; overflow-y: auto; max-height: 55vh; }
.ib-empty { padding: 2rem; color: var(--muted); }
.ib-reply { display: flex; gap: .6rem; padding: .9rem 1.2rem; border-top: 1px solid var(--line); }
.ib-reply textarea { flex: 1; height: 3.4rem; padding: .7rem; border-radius: .5rem; border: 1px solid rgb(255 255 255 / 14%); background: #070b12; color: var(--ice, #e9f2fb); font: inherit; resize: vertical; }
.ib-reply button { width: auto; padding: 0 1.4rem; border-radius: .5rem; border: 1px solid var(--blue-bright); background: #2a6fb8; color: #fff; font: 600 14px inherit; cursor: pointer; }
.ib-note { padding: 0 1.2rem .9rem; color: var(--muted); font-size: 12px; }
.ib .hc-msg { max-width: 70%; }
@media (max-width: 760px) {
    .ib-top h1 { font-size: 1.5rem; }
    .ib-grid { grid-template-columns: 1fr; }
    .ib.has-thread .ib-list { display: none; }
    .ib:not(.has-thread) .ib-thread { display: none; }
    .ib .hc-msg { max-width: 88%; }
}

/* Booking extras (2026-10-22): a closed menu that opens smoothly (Owner, #682), the same blue tick as the return toggle. */
.booking-extras { min-width: 0; max-width: 100%; border: 1px solid rgba(255,255,255,.12); border-radius: 12px; background: rgba(255,255,255,.02); overflow: hidden; }
.booking-extras__toggle { min-width: 0; max-width: 100%; display: flex; align-items: center; gap: .7rem; padding: .85rem 1rem; cursor: pointer; list-style: none; color: #cbd3dd; font: 600 .85rem "Segoe UI", system-ui, sans-serif; }
.booking-extras__toggle::-webkit-details-marker { display: none; }
/* The FAQ's summary spans are big and blue; this summary is a form field, so it says so explicitly. */
.booking-extras .booking-extras__toggle .booking-extras__title { font: inherit; color: inherit; margin: 0; padding: 0; transform: none; transition: none; }
.booking-extras[open] .booking-extras__toggle small { visibility: hidden; }
.booking-extras .booking-extras__toggle .booking-extras__chevron { flex: none; display: block; font-size: 0; }
.booking-extras__toggle small { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #8a95a5; font-weight: 400; }
.booking-extras__chevron { width: .6rem; height: .6rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform .25s ease; margin: -.2rem .2rem 0 0; }
.booking-extras[open] .booking-extras__chevron { transform: rotate(-135deg); margin-top: .2rem; }
.booking-extras__toggle:hover, .booking-extras__toggle:focus-visible { color: #fff; }
.booking-extras__body { padding: .1rem 1rem 1rem; }
.booking-extras__body .field-note { margin: .9rem 0 0; }
.booking-extras[open] .booking-extras__body { animation: booking-extras-open .28s ease both; }
@keyframes booking-extras-open { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .booking-extras[open] .booking-extras__body { animation: none; } .booking-extras__chevron { transition: none; } }
.booking-extras__list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .7rem 1.2rem; }
@media (max-width: 760px) { .booking-extras__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .booking-extras__list { grid-template-columns: 1fr; } }
.booking-extras__item { display: inline-flex; align-items: center; gap: .5rem; cursor: pointer; }
/* One left edge for the title, every box and the note (Owner, #684). */
.booking-extras__item input { width: 1.15rem; min-height: 1.15rem; height: 1.15rem; margin: 0; flex-shrink: 0; accent-color: var(--blue); }
.booking-extras__item { margin: 0; min-height: 1.6rem; }

/* Flight board (2026-10-22): airport picker, two direction buttons, a plain timetable that scrolls sideways on a phone. */
.flight-board__pick { display: flex; flex-wrap: wrap; align-items: end; gap: .8rem 1.2rem; margin: 1rem 0 1.2rem; }
.flight-board__pick label { display: grid; gap: .35rem; flex: 1 1 16rem; }
.flight-board__tabs { display: flex; gap: .5rem; }
.flight-board__scroll { overflow-x: auto; margin: 0 0 .8rem; }
.flight-board__table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.flight-board__table th, .flight-board__table td { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid rgba(255,255,255,.10); white-space: nowrap; }
.flight-board__table th { font-weight: 600; opacity: .75; }
.flight-board__table td:nth-child(3) { white-space: normal; }
.flight-board__new { opacity: .85; }
.flight-board__table tr.is-delayed td:last-child { color: #f0b860; }
.flight-board__table tr.is-cancelled td { opacity: .55; text-decoration: line-through; }
.flight-board__table tr.is-cancelled td:last-child { text-decoration: none; opacity: 1; color: #f07a7a; }
.flight-board-page .flight-board { max-width: min(60rem, 100%); width: 100%; }

/* Route pages (2026-10-23): the price table and the list of other routes. */
.route-page .route-card { max-width: min(54rem, 100%); width: 100%; }
.route-card__scroll { overflow-x: auto; margin: 1rem 0 .4rem; }
.route-card__table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.route-card__table th, .route-card__table td { text-align: left; padding: .6rem .6rem; border-bottom: 1px solid rgba(255,255,255,.10); }
.route-card__table thead th { font-weight: 600; opacity: .75; font-size: .85rem; }
.route-card__table tbody th { font-weight: 600; }
.route-card .form-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.2rem; }
.route-card__others-title { margin: 2rem 0 .6rem; font-size: 1.05rem; }
.route-card__others { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: .45rem 1.2rem; }
.route-card__others small { opacity: .7; }

/* THE HEADER ON A LAPTOP (Owner #1539, Bolt #1544): the Careers link pushed the menu onto
   a second row above the booking button below about 1500px. The link's short word, a
   closer row and a smaller button keep one row in all six languages. */
@media (min-width: 1101px) and (max-width: 1500px) {
    .site-header > nav { gap: .7rem; }
    .site-header .nav-cta-art { max-width: clamp(10.5rem, 15.5vw, 19rem); }
}
/* Russian and Lithuanian at 1200-1365px (Owner #1539, Bolt #1546): still a second row
   after the rule above, by a few dozen pixels. The links close up a little more there;
   Lithuanian also says "Automobiliai" rather than "Automobilių parkas" (i18n). */
@media (min-width: 1101px) and (max-width: 1365px) {
    .site-header > nav { gap: .45rem; }
    .site-header > nav .nav-links a { padding-inline: .3rem; }
}
/* At 1200px Russian and Lithuanian were still 60px over: the menu takes a hair smaller
   capitals there and the booking button gives a little of its width. */
@media (min-width: 1101px) and (max-width: 1250px) {
    .site-header > nav .nav-links a { font-size: .72rem; }
    .site-header .nav-cta-art { max-width: 9.5rem; }
}

/* Reviews: the form on the booking page and the published ones on the front page (#695). */
.review-box{margin:24px auto;padding:20px;border:1px solid var(--line);border-radius:14px;display:grid;gap:10px;max-width:640px;scroll-margin-top:96px}
.review-box h2{margin:0;font-size:1.3rem}
.review-box form{display:grid;gap:8px}.review-box form>.button{justify-self:center}
.review-box textarea,.review-box input[type=text],.review-box input:not([type]){width:100%;min-width:0;box-sizing:border-box}
.review-stars{border:0;margin:0;padding:0;display:flex;flex-direction:row-reverse;justify-content:center;gap:4px}
.review-stars legend{width:100%;margin-bottom:4px;font-size:.9rem;text-align:center}
.review-stars input{position:absolute;opacity:0;width:1px;height:1px}
.review-stars label{font-size:2.2rem;line-height:1;cursor:pointer;color:var(--line);min-width:44px;min-height:44px;display:grid;place-items:center}
.review-stars label:hover,.review-stars label:hover~label,.review-stars input:checked~label{color:var(--blue-bright)}
.review-stars input:focus-visible+label{outline:2px solid var(--blue-bright);outline-offset:2px;border-radius:6px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.review-list{list-style:none;margin:2.5rem 0 0;padding:0;display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
.review-card{padding:18px;border:1px solid var(--line);border-radius:14px;display:grid;gap:8px;align-content:start}
.review-card__stars{margin:0;color:var(--blue-bright);letter-spacing:2px}
.review-card blockquote{margin:0;overflow-wrap:anywhere}
.review-card p.review-card__who{margin:0;font-size:.85rem;opacity:.7}
.review-card__stars .is-off{color:var(--line)}
.review-box p.review-card__stars--big{font-size:2rem;line-height:1.2;text-align:center;letter-spacing:6px}
.review-box h2{text-align:center}
.review-box__quote{margin:0;padding:12px 16px;border-left:2px solid var(--blue-bright);font-style:italic;overflow-wrap:anywhere}
/* Every row of page buttons stands centred at every width (booking page, office pages); they used to rely on
   the section's text-align, which turns left on narrower screens (Owner, 2026-11-04). */
.manage-actions { display: grid; width: max-content; max-width: 100%; margin-inline: auto; }
/* A pair of buttons is one width, the wider one's (Owner's rule: "Confirm" sat
   narrower than "Decline" under it); a button inside a form fills it too. */
.manage-actions .button, .manage-actions form { width: 100%; min-width: var(--button-width); white-space: nowrap; }
@media (max-width: 620px) { .manage-actions { width: min(100%, 17rem); } .manage-actions .button { width: 100%; white-space: normal; } }
.review-card p.review-card__stars{font-size:1.15rem;line-height:1}
.review-card__when{white-space:nowrap}
/* Phones: the help button folds to its icon so it covers no form; the word
   slides out on hover or keyboard focus, and the button steps aside while
   the visitor is typing (Owner, 2026-11-04). Phones and tablets alike: at
   full size it covered the footer's links up to about 1000px. */
@media (max-width: 1024px) {
    .hc-fab { right: 10px; bottom: 10px; gap: 0; padding: 0; width: 44px; height: 44px; justify-content: center; transition: width .25s ease, padding .25s ease, gap .25s ease; }
    .hc-fab__label { max-width: 0; overflow: hidden; white-space: nowrap; transition: max-width .25s ease; }
    .hc-fab:hover, .hc-fab:focus-visible { width: auto; padding: 0 18px 0 14px; gap: 10px; }
    .hc-fab svg { width: 18px; height: 18px; }
    .hc-fab:hover .hc-fab__label, .hc-fab:focus-visible .hc-fab__label { max-width: 8em; }
    body:has(main input:focus, main textarea:focus, main select:focus) .hc-fab { opacity: 0; pointer-events: none; }
}
/* The folded help button's lane beside the footer links - only where those
   links sit in the bottom-right corner. On a phone they are centred above the
   credits, and a lane on one side only pushed them off the axis and onto a
   third line (Owner, 2026-11-05). */
@media (min-width: 621px) and (max-width: 1024px) { .footer-policies { padding-right: 52px; } }
/* THE CONTACT BUTTON SITS MIDWAY between the sentence above it and the rule
   below it (Owner, 2026-11-04): the block's own bottom padding and the grid's
   row gap used to stack under it, 42px below against 16px above. */
@media (min-width: 621px) and (max-width: 1100px) {
    /* The block is as tall as the contacts beside it. Two springs share what
       is left equally; the lower one gives back the grid's row gap, which
       already sits below the block. */
    .footer-top > .footer-maker, .footer-maker { padding-bottom: 0; align-self: stretch; }
    .footer-maker::before, .footer-maker::after { content: ""; }
    .footer-maker::before { order: 1; flex: 1 1 1rem; }
    .footer-maker .footer-cta { order: 2; margin-block: 0; }
    /* The eye measures from the letters, not the line box: the paragraph's
       half-leading below its last line counts as space above, so the button rises by it. */
    .footer-maker::after { order: 3; flex: 1 1 1rem; margin-bottom: calc(-.55rem + .45rem); }
}
@media (max-width: 620px) {
    /* One column: the same air above the button as below it, down to the rule. */
    .footer-maker { padding-bottom: 0; }
    .site-footer .footer-maker .footer-cta { margin-top: 1rem; }
}
.turnstile__note{margin:.5rem 0 0;color:#ff9b94;font-size:.85rem;text-align:center}
/* THE DISPATCHER'S DAY BOARD (#695 point 4). Built only from the site's own
   parts (Owner, 2026-11-05): each ride is a .journey-ticket - its fill, frame,
   glow and status pill - and every colour is a site variable. A request still
   waiting pulses its status dot, as on the booking page; there is no new hue. */
.dd { width: min(100%, var(--page-width)); margin: 0 auto; padding: clamp(1.5rem, 4vw, 3rem) calc(var(--gutter) + var(--text-inset)); }
.dd-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 1.5rem; }
.dd-top h1 { margin: 0; }
.dd-nav { display: flex; align-items: center; gap: .6rem; }
.dd-nav .button { width: auto; min-width: 2.85rem; }
.dd-pick { display: flex; gap: .6rem; margin: 0; }
.dd-date { position: relative; display: grid; place-items: center; min-width: 10rem; min-height: 2.85rem; margin: 0; padding: 0 .8rem; font-size: 1rem; font-weight: 400; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); color: var(--text); cursor: pointer; }
.dd-sum { margin: 1rem 0 1.75rem; color: var(--muted); }
.dd-sum strong { color: var(--text); }
.dd-list { display: grid; gap: 1rem; margin: 0; padding: 0; list-style: none; }
.dd-row.journey-ticket { width: 100%; margin: 0; display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) minmax(9rem, 13rem) 19rem; gap: 1.25rem; align-items: center; padding: 1.1rem 1.5rem; }
.dd-row p { margin: 0; }
.dd-time { display: grid; gap: .3rem; color: var(--blue-bright); font-size: 1.6rem; font-weight: 650; line-height: 1; letter-spacing: -.02em; text-shadow: 0 0 1.2rem color-mix(in srgb, var(--blue) 45%, transparent); }
.dd-time small { color: var(--muted); font-size: .64rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; text-shadow: none; }
.dd-route { color: var(--text); font-weight: 600; }
.dd-row .dd-meta { margin-top: .3rem; color: var(--muted); font-size: .85rem; }
.dd-row .dd-notes { margin-top: .3rem; color: var(--ice); font-size: .85rem; font-style: italic; }
.dd-who { display: grid; gap: .4rem; color: var(--text); font-size: .9rem; overflow-wrap: anywhere; }
.dd-who a { color: var(--blue-bright); }
/* THE STATUS AND ITS BUTTON ARE A PAIR (Owner, 2026-11-05: "a green pill on the
   left and a strange blue square on the right - make them identical"): two
   equal halves, one height, one rounded shape, one typeface - the status
   pill's - told apart only by their colour. */
.dd-act { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: center; gap: .75rem; }
.dd-act > .journey-ticket__status, .dd-act > .button { box-sizing: border-box; width: 100%; min-width: 0; height: 2.85rem; min-height: 2.85rem; padding: 0 .7rem; border-radius: 999px; justify-content: center; font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; box-shadow: inset 0 1px 0 rgb(255 255 255 / 12%), 0 .6rem 1.3rem rgb(0 0 0 / 18%); }
.journey-ticket--off.dd-row .dd-time { color: var(--muted); text-shadow: none; }
/* Waiting and confirmed told apart (Owner, 2026-11-05): a confirmed ride sits on
   a calm card; a request still waiting is lit in --blue-bright. */
.dd-row.journey-ticket--ok { border-color: var(--line); box-shadow: 0 1.2rem 2.4rem rgb(0 0 0 / 30%); }
.dd-row.journey-ticket--wait { border-color: var(--blue-bright); box-shadow: 0 1.8rem 3.6rem rgb(0 0 0 / 38%), 0 0 2.2rem color-mix(in srgb, var(--blue-bright) 30%, transparent); }
.dd-group + .dd-group { margin-top: 2.25rem; }
.dd-group__title { display: flex; align-items: center; gap: .6rem; margin: 0 0 1rem; color: var(--muted); font-size: .72rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.dd-group__title span { color: var(--text); }
@media (max-width: 1000px) {
    .dd-row.journey-ticket { grid-template-columns: 4.25rem minmax(0, 1fr); align-items: start; gap: .75rem 1rem; padding: 1.1rem; }
    .dd-time { font-size: 1.3rem; padding-top: .1rem; }
    .dd-who { grid-column: 2; }
    /* The status and the button stand centred under the card's text (Owner's rule). */
    .dd-act { grid-column: 1 / -1; padding-top: .35rem; }
    /* Arrows either side of the date; Today, when shown, takes the row beneath. */
    .dd-nav { display: grid; grid-template-columns: 2.85rem 1fr 1fr 2.85rem; width: 100%; }
    .dd-pick { display: contents; }
    .dd-nav > .button:first-child { grid-area: 1 / 1; }
    .dd-pick .dd-date { grid-area: 1 / 2 / 2 / 4; min-width: 0; }
    .dd-nav > .button:nth-child(3) { grid-area: 1 / 4; }
    .dd-nav > .button:nth-child(4) { grid-area: 2 / 1 / 3 / 5; width: 100%; }
}
@media print { .dd-nav, .dd-act .button, .site-header, .site-footer { display: none; } .dd-row { break-inside: avoid; } }
/* A REQUEST STILL WAITING (Owner, 2026-11-05): its pill wears the site's own
   green - the "it worked" notice's frame and fill, rgb(120 220 150) - and its
   dot pulses hard. A confirmed ride keeps the plain blue pill of the booking page. */
.dd-row.journey-ticket--wait .journey-ticket__status, .office-ride .journey-ticket--wait .journey-ticket__status { border-color: rgb(120 220 150 / 48%); background: linear-gradient(135deg, rgb(120 220 150 / 16%), rgb(120 220 150 / 4%)); color: rgb(120 220 150); }
.dd-row.journey-ticket--wait .journey-ticket__status::before, .office-ride .journey-ticket--wait .journey-ticket__status::before { animation: dd-pulse 1.1s ease-in-out infinite; }
@keyframes dd-pulse {
    0%, 100% { opacity: 1; transform: scale(1.15); box-shadow: 0 0 .8rem currentColor, 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent); }
    50% { opacity: .15; transform: scale(.7); box-shadow: 0 0 0 currentColor, 0 0 0 .4rem transparent; }
}
@media (prefers-reduced-motion: reduce) {
    .dd-row.journey-ticket--wait .journey-ticket__status::before { animation: none; }
}
/* THE OFFICE CLOCK on the day board (Owner, 2026-11-05): a small .journey-ticket
   with the board's own big glowing digits; the colon breathes once a second. */
.dd-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "office office" "head clock" "nav clock"; align-items: center; gap: 1rem 2rem; margin-bottom: 2rem; }
.dd-head { grid-area: head; }
.dd-clock { grid-area: clock; }
.dd-top > .dd-nav { grid-area: nav; }
.dd-head { min-width: 0; }
.dd-head .dd-sum { margin: .6rem 0 0; }
.dd-top > .dd-nav { justify-self: start; }
.dd-clock.journey-ticket { width: auto; margin: 0; padding: .85rem 2rem 1rem; display: grid; justify-items: center; gap: .3rem; text-align: center; }
.dd-clock__place { color: var(--muted); font-size: .64rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.dd-clock__time { display: flex; align-items: baseline; gap: .35rem; color: var(--blue-bright); font-size: clamp(2.2rem, 3.6vw, 3rem); font-weight: 650; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; text-shadow: 0 0 1.2rem color-mix(in srgb, var(--blue) 45%, transparent); }
.dd-clock__time i { font-style: normal; animation: dd-colon 1s steps(1, end) infinite; }
.dd-clock__time small { color: var(--muted); font-size: .38em; font-weight: 600; letter-spacing: 0; text-shadow: none; }
.dd-clock__date { color: var(--text); font-size: .85rem; white-space: nowrap; }
@keyframes dd-colon { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .dd-clock__time i { animation: none; } }
@media (max-width: 1000px) {
    .dd-top { grid-template-columns: 1fr; grid-template-areas: "office" "head" "clock" "nav"; justify-items: stretch; }
    .dd-clock.journey-ticket { justify-self: center; width: min(100%, 22rem); }
    .dd-top > .dd-nav { justify-self: stretch; }
}
/* THE BOARD'S HEADER AS A PICTURE (Owner, 2026-11-05): the footer has its
   road, so the top gets the home page's road too - day or night by Oslo's
   clock - under the footer's own darkening, turned upside down so the band
   sinks into the page below it. Framed in the site's line and radius. */
.dd-band { position: relative; isolation: isolate; overflow: hidden; padding: clamp(1.5rem, 3.2vw, 2.6rem); border: 1px solid var(--line); border-radius: var(--radius); }
.dd-hero { position: absolute; z-index: -2; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 58%; pointer-events: none; }
.dd-band::after { content: ""; position: absolute; z-index: -1; inset: 0; background: linear-gradient(180deg, rgb(7 11 18 / 72%) 0%, rgb(7 11 18 / 50%) 30%, rgb(7 11 18 / 78%) 65%, var(--night) 100%); pointer-events: none; }
.dd-head h1 { text-shadow: 0 .4rem 1.6rem rgb(0 0 0 / 55%); }
.dd-head .dd-sum { color: var(--ice); }
/* AN AGREED RIDE THE CUSTOMER HAS EDITED (Owner, 2026-11-05) wears the red of
   the Luxury car (its tier colour, rgb(198 90 96)) - the pill in the notice's
   frame-and-fill, the dot pulsing, the card's rim warmed to the same red. */
.dd-row.journey-ticket--changed { border-color: rgb(198 90 96 / 60%); box-shadow: 0 1.8rem 3.6rem rgb(0 0 0 / 38%), 0 0 2.2rem rgb(198 90 96 / 22%); }
.dd-row.journey-ticket--changed::before { background: linear-gradient(90deg, transparent, rgb(198 90 96), transparent); }
.journey-ticket--changed .journey-ticket__status { border-color: rgb(198 90 96 / 55%); background: linear-gradient(135deg, rgb(198 90 96 / 18%), rgb(198 90 96 / 5%)); color: rgb(255 217 217); }
.journey-ticket--changed .journey-ticket__status::before { background: rgb(198 90 96); box-shadow: 0 0 .6rem rgb(198 90 96); animation: dd-pulse 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .journey-ticket--changed .journey-ticket__status::before { animation: none; } }
/* THE DISPATCHER'S PANEL AS ONE SYSTEM (Owner, 2026-11-05): the same doors on
   every page - rides, chats with the unread count, the duty light - and one
   picture header; the office's corner button opens its conversations. */
.office-nav { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.4rem; margin: 0 0 1rem; }
.office-nav__link { position: relative; color: var(--muted); font-size: .72rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; text-decoration: none; }
.office-nav__link:hover, .office-nav__link.is-active { color: var(--text); }
.office-nav__link.is-active::after { content: ""; position: absolute; left: 0; right: 50%; bottom: -.4rem; height: 2px; background: var(--blue-bright); }
.office-nav__count { display: inline-grid; place-items: center; min-width: 1.35rem; height: 1.35rem; margin-left: .35rem; padding: 0 .35rem; border-radius: 999px; background: var(--blue); color: var(--night); font-size: .66rem; letter-spacing: 0; }
.office-nav__duty { display: inline-flex; align-items: center; gap: .45rem; margin-left: auto; color: var(--muted); font-size: .72rem; font-weight: 600; letter-spacing: .08em; }
.office-nav__duty i { width: .5rem; height: .5rem; border-radius: 50%; background: var(--line); }
.office-nav__duty.is-on { color: rgb(120 220 150); }
.office-nav__duty.is-on i { background: rgb(120 220 150); box-shadow: 0 0 .6rem rgb(120 220 150); }
.dd-band .office-nav { position: relative; }
.dd-top > .office-nav { grid-area: office; margin: 0; }
.office-fab .hc-dot { display: inline-block; }
/* The ride page is as wide as the board (Owner, 2026-11-05: "why so narrow"):
   the picture header across, then the journey card beside its details. */
.office-ride__grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 1.5rem; align-items: start; }
.office-ride__side { display: grid; gap: 0; }
.office-ride__side .manage-actions { margin-top: 1.5rem; }
@media (max-width: 1000px) { .office-ride__grid { grid-template-columns: minmax(0, 1fr); gap: 0; } }
.office-ride__band { display: grid; gap: .5rem; }
.office-ride__band h1 { margin: 0; text-shadow: 0 .4rem 1.6rem rgb(0 0 0 / 55%); }
.office-ride__band .dd-sum { margin: 0; color: var(--ice); }
.office-ride > .form-notice { margin: 1.5rem 0 0; }
.office-ride__alert { border-color: rgb(198 90 96 / 55%); background: linear-gradient(135deg, rgb(198 90 96 / 18%), rgb(198 90 96 / 5%)); color: rgb(255 217 217); }
.office-ride .journey-ticket { width: 100%; margin: 1.5rem 0 0; }
.office-ride__label { color: var(--muted); font-size: .64rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.office-ride__facts { margin: 0; padding: .4rem 1.5rem 1.1rem; }
.office-ride__facts div { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 1rem; padding: .8rem 0; border-bottom: 1px solid var(--line); }
.office-ride__facts div:last-child { border-bottom: 0; }
.office-ride__facts dt { color: var(--muted); font-size: .64rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; line-height: 1.6; }
.office-ride__contact dd { display: grid; gap: .45rem; }
.office-ride__contact a.dd-line { text-decoration: none; }
.office-ride__contact a.dd-line:hover { text-decoration: underline; }
.office-ride__facts dd { margin: 0; color: var(--text); font-size: .92rem; overflow-wrap: anywhere; }
.office-ride__facts a { color: var(--blue-bright); }
.office-ride__form { margin-top: 1.5rem; }
@media (max-width: 620px) { .office-ride__facts div { grid-template-columns: 1fr; gap: .25rem; } }
.office-ride__band h1 { font-size: clamp(2rem, 4vw, 2.9rem); line-height: 1.05; }
.office-ride__alert::before { display: none; }
/* THE BOARD'S HEADER, TIDIED (Owner, 2026-11-05). The summary is a row of
   facts that never split - "Pending: 3" stays one piece - with the dots drawn
   here; on a phone the day takes its own line and the title, the day and the
   facts stand on the card's axis. */
.dd-head .dd-sum { display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .55rem; }
.dd-sum > span { white-space: nowrap; }
.dd-sum > span + span::before { content: "·"; margin-right: .55rem; }
@media (max-width: 1000px) {
    .dd-head { text-align: center; }
    .dd-head .dd-sum { justify-content: center; }
    .dd-sum__day { flex-basis: 100%; }
    .dd-sum > .dd-sum__day + span::before { content: none; }
}
/* The day's arrows: round, the date pill's own height, a drawn chevron in
   --blue-bright instead of a text glyph (Owner: "tiny arrows you can hardly
   see"). The date is the board's own text in the middle of its pill; the
   browser's date field lies over it unseen, so a tap anywhere opens the
   calendar and no native arrow or left-pinned digits show (Owner). */
.dd-nav .dd-step { width: 2.85rem; min-width: 2.85rem; height: 2.85rem; min-height: 2.85rem; padding: 0; border-radius: 50%; }
.dd-step svg { position: relative; width: 1.45rem; height: 1.45rem; fill: none; stroke: var(--blue-bright); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: transform .2s; }
.dd-nav > .dd-step:first-child:hover svg { transform: translateX(-2px); }
.dd-nav > .dd-step:nth-child(3):hover svg { transform: translateX(2px); }
.dd-date__text { font-variant-numeric: tabular-nums; pointer-events: none; }
.dd-date:hover { border-color: var(--blue-bright); }
.dd-date:focus-within { outline: 2px solid var(--blue-bright); outline-offset: 2px; }
.dd-date input[type=date] { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0; border: 0; opacity: 0; font: inherit; color-scheme: dark; cursor: pointer; }
.dd-date input[type=date]::-webkit-calendar-picker-indicator { position: absolute; inset: 0; width: auto; height: auto; margin: 0; padding: 0; cursor: pointer; }
/* Icons, not bare text (Owner, 2026-11-05): the footer's own blue icons - the
   pin for the route, a figure for the name, the handset for the phone. */
.dd-line { display: flex; align-items: flex-start; gap: .55rem; }
.dd-line .footer-icon { width: 1rem; height: 1lh; }
.dd-who a.dd-line { text-decoration: none; }
.dd-who a.dd-line:hover { text-decoration: underline; }
.dd-main > p:not(.dd-route) { padding-left: 1.55rem; }
.dd-meta > span { white-space: nowrap; }
