/* ============================================================
   Domolytics — design v3, the shared sheet (request 202, tasks 0217, 0219, 0226, 0227)

   A trial of a new look on the pages that have a v3 view: the travel
   welcome page (`Views/home/travel_v3.php`), `/register` and `/login`
   (whose own rules are in auth_v3.css) and `/travel` with no trips and with
   trips (`Views/travel/onboarding_v3.php`, `home_v3.php`), and the trips list
   (`overview_v3.php`, task 0230) and the visited countries
   (`visited_countries_v3.php`, task 0234), and the cities, flights and
   stays lists (`cities_v3`, `all_flights_v3`, `all_stays_v3`, task 0236),
   and the single-trip dashboard (`trip_dashboard_v3.php`, task 0238),
   and the trip pages and the companions page (tasks 0240a–0240i).
   This file holds the tokens,
   buttons, the header and the footer every v3 page uses, then the
   welcome page's sections, then the two travel pages'. It was travel_v3.css
   until task 0219 made it shared.
   Loaded after tokens_v2 / main_v2 / components_v2, so the shared
   mechanisms keep working unchanged: the focus ring, `.sr-only`,
   the skip link, text size, monochrome, the theme and language
   controls. Every rule is scoped under the `.v3` class — this file
   cannot restyle any other page. A public page puts the class on
   <body>; an app-shell page, whose rail, top bar and footer stay v2,
   puts it on its content only (task 0226, tech/3-ui.md). Only the
   two whole-page rules under "base" name `body.v3`.

   Colour: v3 has its own palette, so it carries its own tokens,
   declared once at the top for each mode (light, dark, monochrome,
   monochrome + dark) — the same rule tokens_v2.css follows: no
   component rule below names a colour literal.

   Sizes are in rem, so the text-size control scales the page.
   ============================================================ */

/* ---- tokens: light (default) -------------------------------- */
.v3 {
    --v3-bg: #f4f7fc;
    --v3-bg-hero: #eef4fb;
    --v3-card: #ffffff;
    --v3-card-2: #f7f9fd;
    --v3-border: #e1e8f2;
    --v3-text: #0f1f3d;
    --v3-muted: #4a5873;        /* 7.0:1 on --v3-card */
    --v3-primary: #1261d6;      /* 5.4:1 against white text */
    --v3-primary-hover: #0d4fb3;
    --v3-on-primary: #ffffff;
    --v3-link: #1158c4;
    --v3-blue-bg: #e5efff;   --v3-blue-fg: #1261d6;
    --v3-green-bg: #e2f5ea;  --v3-green-fg: #177544;
    --v3-violet-bg: #eeeafe; --v3-violet-fg: #5b3fc4;
    --v3-teal-bg: #dcf3f4;   --v3-teal-fg: #0b6770;
    --v3-amber-bg: #fdf1d6;  --v3-amber-fg: #8a5a00;
    --v3-after-bg: #eaf7ef;
    --v3-after-title: #146b3b;  /* 6.1:1 on --v3-after-bg */
    --v3-shadow: 0 1px 2px rgba(15, 31, 61, .05), 0 6px 20px rgba(15, 31, 61, .06);
    --v3-final-bg: linear-gradient(180deg, #e3effb 0%, #cfe4f7 100%);
    --v3-hero-fade: linear-gradient(180deg, #f7fafe 0%, #eaf2fb 100%);
    --v3-hero-scrim: rgba(10, 20, 38, .62);  /* over a photo: --v3-on-hero keeps 4.8:1 on a white pixel */
    --v3-on-hero: #ffffff;
    --v3-input-bg: #ffffff;
    --v3-input-border: #77849b;  /* 3.7:1 on white — a field edge is a UI component */
    --v3-track: #e1e8f2;
    --v3-danger: #b42318;       /* 6.5:1 on --v3-card */
    /* A delete icon's fill and the bin on it (task 0268) — a pair: change them together. */
    --v3-danger-fill: #b42318;  /* --v3-on-danger keeps 6.5:1 on it */
    --v3-danger-fill-hover: #8f1a11;
    --v3-on-danger: #ffffff;
    /* An edit icon's fill, edge and pencil (tasks 0269–0271). The fill is the operator's
       yellow, #feffcf (task 0271): too light to carry a white pencil or to show an edge on
       --v3-card, so the pencil is dark and the edge has its own colour. */
    --v3-edit-fill: #feffcf; --v3-edit-fill-hover: #feffa8; --v3-edit-border: #8a6d00; --v3-on-edit: #5c3d00;

    background: var(--v3-bg);
    color: var(--v3-text);
}

/* ---- tokens: dark ------------------------------------------- */
:root[data-theme="dark"] .v3 {
    --v3-bg: #0c1422;
    --v3-bg-hero: #0f1a2c;
    --v3-card: #15213a;
    --v3-card-2: #1a2743;
    --v3-border: #2a3858;
    --v3-text: #e9eff9;
    --v3-muted: #a9b7cd;
    --v3-primary: #6ea8ff;      /* 7.9:1 against --v3-on-primary */
    --v3-primary-hover: #8dbbff;
    --v3-on-primary: #0a1426;
    --v3-link: #8dbbff;
    --v3-blue-bg: #1c3259;   --v3-blue-fg: #9cc3ff;
    --v3-green-bg: #173b2b;  --v3-green-fg: #7fd9a6;
    --v3-violet-bg: #2c2657; --v3-violet-fg: #c3b5ff;
    --v3-teal-bg: #123a40;   --v3-teal-fg: #7fd6dd;
    --v3-amber-bg: #3d2f12;  --v3-amber-fg: #ffd27a;
    --v3-after-bg: #13301f;
    --v3-after-title: #8ee0b1;
    --v3-shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 6px 20px rgba(0, 0, 0, .25);
    --v3-final-bg: linear-gradient(180deg, #13223b 0%, #0f1c31 100%);
    --v3-hero-fade: linear-gradient(180deg, #0f1a2c 0%, #0c1422 100%);
    --v3-hero-scrim: rgba(10, 20, 38, .7);
    --v3-on-hero: #ffffff;
    --v3-input-bg: #0f1a2e;
    --v3-input-border: #5d6f91;
    --v3-track: #2a3858;
    --v3-danger: #ff9a8f;
    /* Brighter than light's: 3.3:1 against --v3-card, and --v3-on-danger keeps 4.8:1 on it. */
    --v3-danger-fill: #d92d20;
    --v3-danger-fill-hover: #f04438;
    --v3-on-danger: #ffffff;
    /* The same yellow: on a dark card the fill is its own edge. */
    --v3-edit-fill: #feffcf; --v3-edit-fill-hover: #e9eb84; --v3-edit-border: #feffcf; --v3-on-edit: #5c3d00;
}

/* ---- tokens: monochrome (composes with dark, like tokens_v2) -- */
:root[data-mono] .v3 {
    --v3-bg: #ffffff; --v3-bg-hero: #ffffff; --v3-card: #ffffff; --v3-card-2: #ffffff;
    --v3-border: #000000; --v3-text: #000000; --v3-muted: #000000;
    --v3-primary: #000000; --v3-primary-hover: #333333; --v3-on-primary: #ffffff; --v3-link: #000000;
    --v3-blue-bg: #ffffff; --v3-blue-fg: #000000; --v3-green-bg: #ffffff; --v3-green-fg: #000000;
    --v3-violet-bg: #ffffff; --v3-violet-fg: #000000;
    --v3-teal-bg: #ffffff; --v3-teal-fg: #000000;
    --v3-amber-bg: #ffffff; --v3-amber-fg: #000000;
    --v3-after-bg: #ffffff; --v3-after-title: #000000;
    --v3-shadow: none;
    --v3-final-bg: #ffffff; --v3-hero-fade: #ffffff;
    --v3-hero-scrim: rgba(255, 255, 255, .85); --v3-on-hero: #000000;
    --v3-input-bg: #ffffff; --v3-input-border: #000000; --v3-track: #ffffff; --v3-danger: #000000;
    --v3-danger-fill: #000000; --v3-danger-fill-hover: #333333; --v3-on-danger: #ffffff;
    --v3-edit-fill: #000000; --v3-edit-fill-hover: #333333; --v3-edit-border: #000000; --v3-on-edit: #ffffff;
}
:root[data-mono][data-theme="dark"] .v3 {
    --v3-bg: #000000; --v3-bg-hero: #000000; --v3-card: #000000; --v3-card-2: #000000;
    --v3-border: #ffffff; --v3-text: #ffffff; --v3-muted: #ffffff;
    --v3-primary: #ffffff; --v3-primary-hover: #cccccc; --v3-on-primary: #000000; --v3-link: #ffffff;
    --v3-blue-bg: #000000; --v3-blue-fg: #ffffff; --v3-green-bg: #000000; --v3-green-fg: #ffffff;
    --v3-violet-bg: #000000; --v3-violet-fg: #ffffff;
    --v3-teal-bg: #000000; --v3-teal-fg: #ffffff;
    --v3-amber-bg: #000000; --v3-amber-fg: #ffffff;
    --v3-after-bg: #000000; --v3-after-title: #ffffff;
    --v3-final-bg: #000000; --v3-hero-fade: #000000;
    --v3-hero-scrim: rgba(0, 0, 0, .8); --v3-on-hero: #ffffff;
    --v3-input-bg: #000000; --v3-input-border: #ffffff; --v3-track: #000000; --v3-danger: #ffffff;
    --v3-danger-fill: #ffffff; --v3-danger-fill-hover: #cccccc; --v3-on-danger: #000000;
    --v3-edit-fill: #ffffff; --v3-edit-fill-hover: #cccccc; --v3-edit-border: #ffffff; --v3-on-edit: #000000;
}
:root[data-mono] .v3 img,
:root[data-mono] .v3 .v3-flag { filter: grayscale(1); }

/* ---- base ---------------------------------------------------- */
/* A short page (login) still fills the window, so the footer sits at the bottom and no
   strip of the v2 ground shows below it (task 0220). */
body.v3 { min-block-size: 100vh; display: flex; flex-direction: column; }
body.v3 > main { flex: 1 0 auto; }
/* A trip photo's size, shared by the recent-trip cards and the list rows (task 0235). */
.v3 { --v3-trip-photo-w: 12.5rem; --v3-trip-photo-h: 6.25rem; }
.v3 .v3-wrap { max-width: 80rem; margin-inline: auto; padding-inline: 1.5rem; }
.v3 h1, .v3 h2, .v3 h3 { color: var(--v3-text); letter-spacing: -0.02em; }
.v3 p { margin: 0; }
.v3 ul, .v3 ol { list-style: none; margin: 0; padding: 0; }
.v3 .v3-flip { inline-size: 1em; block-size: 1em; flex: none; }
[dir="rtl"] .v3 .v3-flip { transform: scaleX(-1); }

/* ---- buttons ------------------------------------------------- */
.v3 .v3-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    min-block-size: 2.5rem; padding: .5rem 1.1rem;
    border-radius: 999px; border: 2px solid transparent;
    font-weight: 600; font-size: .9375rem; line-height: 1.2;
    text-decoration: none; white-space: nowrap;
    transition: background-color .15s, border-color .15s, color .15s;
}
.v3 .v3-btn--lg { min-block-size: 3rem; padding: .7rem 1.6rem; font-size: 1rem; border-radius: .75rem; }
.v3 .v3-btn--primary { background: var(--v3-primary); color: var(--v3-on-primary); }
.v3 .v3-btn--primary:hover { background: var(--v3-primary-hover); }
.v3 .v3-btn--outline { background: var(--v3-card); color: var(--v3-link); border-color: var(--v3-primary); }
.v3 .v3-btn--outline:hover { background: var(--v3-blue-bg); }
.v3 .v3-btn--quiet { color: var(--v3-text); }
.v3 .v3-btn--light { background: var(--v3-card); color: var(--v3-text); border-color: var(--v3-border); box-shadow: var(--v3-shadow); }
.v3 .v3-btn--light:hover { border-color: var(--v3-primary); }
.v3 .v3-btn svg { inline-size: 1.1em; block-size: 1.1em; flex: none; }
.v3 .v3-btn--quiet:hover { text-decoration: underline; }
.v3 .v3-link {
    display: inline-flex; align-items: center; gap: .35rem;
    color: var(--v3-link); font-weight: 600; font-size: .9375rem; text-decoration: none;
}
.v3 .v3-link:hover { text-decoration: underline; }

/* ---- header -------------------------------------------------- */
.v3 .v3-nav { background: var(--v3-card); border-block-end: 1px solid var(--v3-border); }
.v3 .v3-nav__inner {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: .75rem 1.25rem; min-block-size: 4rem; padding-block: .6rem;
}
.v3 .v3-logo { display: inline-flex; align-items: center; gap: .6rem; color: var(--v3-text); text-decoration: none; font-weight: 800; }
/* The TD tile keeps its shape, letters and the v2 gradient and glow (story; task
   0218). Only the size is v3's. Colour comes from the v2 `.logo-mark` rule and its
   tokens, so dark and monochrome follow the v2 pages. */
.v3 .v3-logo .logo-mark {
    inline-size: 2.4rem; block-size: 2.4rem; border-radius: .7rem;
    font-size: .9rem;
}
/* Tile, then plane, then name, whatever the markup order. */
.v3 .v3-logo .logo-mark { order: 0; }
.v3 .v3-logo__plane { order: 1; }
.v3 .v3-logo .brand-name { order: 2; }
.v3 .v3-logo__plane { inline-size: 1.6rem; block-size: 1.6rem; flex: none; }
.v3 .v3-logo__plane-top  { fill: var(--v3-primary); }
.v3 .v3-logo__plane-fold { fill: var(--v3-primary-hover); }
[dir="rtl"] .v3 .v3-logo__plane { transform: scaleX(-1); }
.v3 .v3-logo .brand-name__main { font-size: 1.25rem; color: var(--v3-link); }
.v3 .v3-logo .brand-name__suffix { color: var(--v3-muted); }
.v3 .v3-nav__tools { display: flex; align-items: center; flex-wrap: wrap; gap: .6rem; }

/* ---- hero ---------------------------------------------------- */
.v3 .v3-hero {
    position: relative; overflow: hidden;
    background: var(--v3-hero-fade);
    min-block-size: 19rem;
}
/* The photo fills the inline-end two thirds and fades out under the text. */
.v3 .v3-hero__photo {
    position: absolute; inset-block: 0; inset-inline-end: 0;
    inline-size: 66%; block-size: 100%; object-fit: cover; object-position: 70% 50%;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 32%);
            mask-image: linear-gradient(to right, transparent 0%, #000 32%);
}
[dir="rtl"] .v3 .v3-hero__photo {
    -webkit-mask-image: linear-gradient(to left, transparent 0%, #000 32%);
            mask-image: linear-gradient(to left, transparent 0%, #000 32%);
}
.v3 .v3-hero__inner { position: relative; padding-block: 2rem 2.25rem; }
.v3 .v3-hero h1 {
    max-inline-size: 13em; margin: 0 0 .9rem;
    font-size: clamp(2rem, 4.2vw, 2.75rem); line-height: 1.1; font-weight: 800;
}
.v3 .v3-hero__sub { max-inline-size: 24rem; font-size: 1.0625rem; line-height: 1.5; color: var(--v3-text); }
.v3 .v3-hero__cta { display: flex; flex-wrap: wrap; gap: .75rem; margin-block: 1.4rem 1.1rem; }
.v3 .v3-hero__tags { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; font-size: .9375rem; }
.v3 .v3-hero__tags li { display: inline-flex; align-items: center; gap: .4rem; }
.v3 .v3-hero__tags svg { inline-size: 1.1rem; block-size: 1.1rem; color: var(--v3-link); }
/* Behind the text the photo is faded but not gone; a soft plate keeps 4.5:1 on any
   part of it. */
.v3 .v3-hero__inner > * { position: relative; }
.v3 .v3-hero__sub, .v3 .v3-hero__tags { text-shadow: 0 0 .6rem var(--v3-bg-hero), 0 0 .3rem var(--v3-bg-hero); }

/* ---- two-column body ----------------------------------------- */
.v3 .v3-grid {
    display: grid; grid-template-columns: minmax(0, 1.28fr) minmax(0, 1fr);
    gap: 1.75rem; padding-block: 1.25rem 2rem;
}
.v3 .v3-col { display: flex; flex-direction: column; gap: 1.25rem; min-inline-size: 0; }
.v3 .v3-card {
    background: var(--v3-card); border: 1px solid var(--v3-border);
    border-radius: 1rem; box-shadow: var(--v3-shadow);
}

/* icons in round tiles */
.v3 .v3-icon {
    display: inline-grid; place-items: center; flex: none;
    inline-size: 3.1rem; block-size: 3.1rem; border-radius: 50%;
}
.v3 .v3-icon svg { inline-size: 1.5rem; block-size: 1.5rem; }
.v3 .v3-icon--blue   { background: var(--v3-blue-bg);   color: var(--v3-blue-fg); }
.v3 .v3-icon--green  { background: var(--v3-green-bg);  color: var(--v3-green-fg); }
.v3 .v3-icon--violet { background: var(--v3-violet-bg); color: var(--v3-violet-fg); }
.v3 .v3-icon--teal   { background: var(--v3-teal-bg);   color: var(--v3-teal-fg); }
.v3 .v3-icon--amber  { background: var(--v3-amber-bg);  color: var(--v3-amber-fg); }
.v3 .v3-icon--sm { inline-size: 2.4rem; block-size: 2.4rem; }
.v3 .v3-icon--sm svg { inline-size: 1.2rem; block-size: 1.2rem; }
.v3 .v3-icon--primary { background: var(--v3-primary); color: var(--v3-on-primary); }
:root[data-mono] .v3 .v3-icon { border: 1px solid var(--v3-border); }

/* features */
.v3 .v3-features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; }
.v3 .v3-feature { padding: 1.1rem 1.2rem 1.3rem; }
.v3 .v3-feature h3 { margin: .8rem 0 .4rem; font-size: 1.0625rem; font-weight: 700; }
.v3 .v3-feature p { font-size: .9063rem; line-height: 1.5; color: var(--v3-muted); }

/* trips */
.v3 .v3-trips__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-block-end: .9rem; }
.v3 .v3-trips__head h2 { margin: 0 0 .15rem; font-size: 1.5rem; font-weight: 800; }
.v3 .v3-trips__head p { color: var(--v3-muted); font-size: .9375rem; }
.v3 .v3-trips__list { display: flex; flex-direction: column; gap: .6rem; }
.v3 .v3-trip { display: flex; align-items: center; gap: 1rem; padding: .5rem 1.25rem .5rem .5rem; }
[dir="rtl"] .v3 .v3-trip { padding: .5rem .5rem .5rem 1.25rem; }
.v3 .v3-trip__photo { inline-size: 5.75rem; block-size: 3.9rem; object-fit: cover; border-radius: .6rem; flex: none; }
.v3 .v3-trip__body { flex: 1; min-inline-size: 0; }
.v3 .v3-trip__name { display: flex; align-items: center; gap: .5rem; margin: 0; font-size: 1rem; font-weight: 700; }
.v3 .v3-flag { inline-size: 1.15rem; block-size: .77rem; border-radius: 2px; flex: none; box-shadow: 0 0 0 1px var(--v3-border); }
.v3 .v3-trip__dates { font-size: .875rem; color: var(--v3-muted); margin-block: .1rem .3rem; }
.v3 .v3-trip__meta { display: flex; flex-wrap: wrap; gap: .3rem 1.5rem; font-size: .8125rem; color: var(--v3-muted); }
.v3 .v3-trip__meta > span { display: inline-flex; align-items: center; gap: .35rem; }
.v3 .v3-trip__meta svg { inline-size: .9rem; block-size: .9rem; }
.v3 .v3-trip__cost { font-size: 1.2rem; font-weight: 800; white-space: nowrap; }

/* how it works */
.v3 .v3-how { padding: 1.4rem 1.5rem 1.6rem; }
.v3 .v3-how h2 { margin: 0 0 .3rem; font-size: 1.5rem; font-weight: 800; }
.v3 .v3-how__sub { color: var(--v3-text); font-size: .9375rem; }
.v3 .v3-steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; margin-block-start: 1.4rem; counter-reset: none; }
.v3 .v3-steps li { position: relative; }
.v3 .v3-steps__num {
    position: relative; z-index: 1;
    display: inline-grid; place-items: center;
    inline-size: 2rem; block-size: 2rem; border-radius: 50%;
    background: var(--v3-primary); color: var(--v3-on-primary); font-weight: 700; font-size: .9375rem;
}
/* the dashed line from one number to the next */
.v3 .v3-steps li:not(:last-child)::after {
    content: ""; position: absolute; inset-block-start: 1rem;
    inset-inline-start: 2.6rem; inset-inline-end: -.6rem;
    border-block-start: 2px dashed var(--v3-border);
}
.v3 .v3-steps h3 { margin: .7rem 0 .3rem; font-size: .875rem; font-weight: 700; line-height: 1.35; }
.v3 .v3-steps p { font-size: .8125rem; line-height: 1.45; color: var(--v3-muted); }

/* before / after */
.v3 .v3-compare {
    display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center; gap: 1rem; padding: 1rem;
}
.v3 .v3-compare h3 { margin: 0 0 .7rem; font-size: 1rem; font-weight: 700; }
.v3 .v3-compare__before { background: var(--v3-card-2); border-radius: .8rem; padding: .9rem 1rem; align-self: stretch; }
.v3 .v3-compare__before li { display: flex; align-items: center; gap: .6rem; padding-block: .3rem; font-size: .875rem; color: var(--v3-muted); }
.v3 .v3-dot { inline-size: .55rem; block-size: .55rem; border-radius: 2px; border: 1.5px solid currentColor; flex: none; }
.v3 .v3-compare__arrow { color: var(--v3-muted); font-size: 1.4rem; display: inline-flex; }
.v3 .v3-compare__after {
    background: var(--v3-after-bg); border-radius: .8rem; padding: .9rem 1rem; align-self: stretch;
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: .3rem;
    font-size: .875rem;
}
.v3 .v3-compare__after h3 { align-self: flex-start; color: var(--v3-after-title); }
.v3 .v3-compare__trip { font-weight: 700; }
.v3 .v3-compare__down { inline-size: 1.1rem; block-size: 1.1rem; color: var(--v3-after-title); }
:root[data-mono] .v3 .v3-compare__before,
:root[data-mono] .v3 .v3-compare__after { border: 1px solid var(--v3-border); }

/* ---- closing call to action ----------------------------------- */
.v3 .v3-final {
    position: relative; overflow: hidden;
    background: var(--v3-final-bg);
    min-block-size: 9rem; display: grid; place-items: center;
    padding: 1.5rem 1rem;
}
.v3 .v3-final__photo {
    position: absolute; inset-block: 0; block-size: 100%; object-fit: cover;
}
.v3 .v3-final__photo--start {
    inset-inline-start: 0; inline-size: 30%;
    -webkit-mask-image: linear-gradient(to right, #000 60%, transparent);
            mask-image: linear-gradient(to right, #000 60%, transparent);
}
.v3 .v3-final__photo--end {
    inset-inline-end: 0; inline-size: 18%;
    -webkit-mask-image: linear-gradient(to left, #000 65%, transparent);
            mask-image: linear-gradient(to left, #000 65%, transparent);
}
[dir="rtl"] .v3 .v3-final__photo--start {
    -webkit-mask-image: linear-gradient(to left, #000 60%, transparent);
            mask-image: linear-gradient(to left, #000 60%, transparent);
}
[dir="rtl"] .v3 .v3-final__photo--end {
    -webkit-mask-image: linear-gradient(to right, #000 65%, transparent);
            mask-image: linear-gradient(to right, #000 65%, transparent);
}
.v3 .v3-final__inner { position: relative; text-align: center; max-inline-size: 32rem; }
.v3 .v3-final h2 { margin: 0 0 .3rem; font-size: 1.5rem; font-weight: 800; }
.v3 .v3-final p { margin-block-end: 1rem; }

/* ---- footer -------------------------------------------------- */
.v3 .v3-footer { background: var(--v3-card); border-block-start: 1px solid var(--v3-border); padding-block: 1.1rem; font-size: .875rem; color: var(--v3-muted); }
.v3 .v3-footer a { color: var(--v3-link); }
.v3 .v3-footer__brand { margin-block-end: .5rem; }
/* Underlined: in monochrome the link colour equals the text colour. */
.v3 .v3-footer__brand a { text-decoration: underline; }
.v3 .v3-footer .footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem 1rem; border: 0; padding: 0; margin: 0; }

/* ---- tablet: one column --------------------------------------- */
@media (max-width: 960px) {
    .v3 .v3-grid { grid-template-columns: minmax(0, 1fr); }
    .v3 .v3-hero__photo { inline-size: 55%; opacity: .75; }
}

/* ---- phone (≤640px, tech/3-ui.md) ----------------------------- */
@media (max-width: 640px) {
    .v3 .v3-wrap { padding-inline: 1rem; }
    .v3 .v3-nav__tools { gap: .45rem; }
    .v3 .v3-btn { min-block-size: 2.25rem; padding: .4rem .85rem; font-size: .875rem; }
    .v3 .v3-btn--lg { min-block-size: 2.75rem; }

    /* The photo becomes a banner above the text instead of sitting behind it. */
    .v3 .v3-hero { min-block-size: 0; }
    .v3 .v3-hero__photo {
        position: static; display: block; inline-size: 100%; block-size: 11rem; opacity: 1;
        -webkit-mask-image: none; mask-image: none;
    }
    .v3 .v3-hero__inner { padding-block: 1.25rem 1.5rem; }
    .v3 .v3-hero__cta .v3-btn { flex: 1 1 100%; }

    .v3 .v3-features { grid-template-columns: minmax(0, 1fr); gap: .75rem; }
    .v3 .v3-feature { display: grid; grid-template-columns: auto 1fr; column-gap: 1rem; align-items: center; }
    .v3 .v3-feature .v3-icon { grid-row: span 2; }
    .v3 .v3-feature h3 { margin: 0 0 .2rem; }

    .v3 .v3-trips__head { flex-wrap: wrap; align-items: flex-start; }
    .v3 .v3-trip { flex-wrap: wrap; padding: .5rem; }
    [dir="rtl"] .v3 .v3-trip { padding: .5rem; }
    .v3 .v3-trip__photo { inline-size: 4.5rem; block-size: 3.1rem; }
    .v3 .v3-trip__cost { inline-size: 100%; text-align: end; padding-inline-end: .5rem; font-size: 1.05rem; }

    .v3 .v3-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 1.25rem; }
    .v3 .v3-steps li::after { display: none; }

    .v3 .v3-compare { grid-template-columns: minmax(0, 1fr); }
    .v3 .v3-compare__arrow { justify-self: center; transform: rotate(90deg); }
    [dir="rtl"] .v3 .v3-compare__arrow { transform: rotate(-90deg); }

    /* Decorative only, and behind the heading at this width. */
    .v3 .v3-final__photo { display: none; }
}

/* ---- motion --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .v3 .v3-btn { transition: none; }
}

/* ============================================================
   `/travel` with no trips (request 204, task 0226)
   Inside the app shell: `.v3` sits on the page's own wrapper, and the
   rail, top bar and footer stay v2 (story). The hero, cards, icon
   tiles and steps above are reused; only what the welcome page does
   not have is below.
   ============================================================ */

/* The content column's padding is dropped so the hero runs edge to edge,
   as in the design; the inner parts keep the shell's gutter, so they line
   up with the breadcrumbs above. */
.content.v3-bleed { padding-block: 0; }
.content.v3-bleed > .container { padding-inline: 0; }
.content.v3-bleed .v3-wrap { max-width: none; padding-inline: var(--shell-gutter); }

.v3 .v3-tripless { container-type: inline-size; }
.v3 .v3-tripless__body { display: flex; flex-direction: column; gap: 1.5rem; padding-block: 1.25rem 2rem; }

/* ---- the hero photo and its example trip ----------------------
   The photo is cut from the design image with the example card
   painted out; the real card sits over that spot. Both are placed
   in units of the photo's height (cqh), and the photo keeps its
   ratio and is cropped from its far side only, so the card always
   lands on the same spot at any size — including text size 200%. */
.v3 .v3-hero__media {
    position: absolute; inset-block: 0; inset-inline-end: 0;
    aspect-ratio: 1002 / 284; max-inline-size: 100%;
    container-type: size; overflow: hidden;
}
.v3 .v3-hero__media > img {
    position: absolute; inset: 0; inline-size: 100%; block-size: 100%;
    object-fit: cover; object-position: right center;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 30%);
            mask-image: linear-gradient(to right, transparent 0%, #000 30%);
}
/* Mirrored under RTL, so the photo fades towards the text on either side;
   the mask flips with it. */
[dir="rtl"] .v3 .v3-hero__media > img { transform: scaleX(-1); }

.v3 .v3-example {
    position: absolute; inset-block-start: 22cqh; inset-inline-end: 97.5cqh;
    inline-size: 111cqh; min-block-size: 68.5cqh;
    display: flex; align-items: flex-start; gap: .9em; padding: .9em 1em;
    font-size: 5.4cqh; line-height: 1.3;
    background: var(--v3-card); color: var(--v3-text);
    border-radius: .9em; box-shadow: var(--v3-shadow);
}
:root[data-mono] .v3 .v3-example { border: 1px solid var(--v3-border); }
.v3 .v3-example img {
    position: static; inline-size: 6.4em; block-size: 5.6em; flex: none;
    object-fit: cover; border-radius: .5em;
}
.v3 .v3-example__name { display: flex; align-items: center; gap: .45em; margin: 0 0 .35em; font-size: 1.15em; font-weight: 700; }
.v3 .v3-example .v3-flag { inline-size: 1.15em; block-size: .77em; }
.v3 .v3-example li { display: flex; align-items: center; gap: .5em; padding-block: .12em; font-size: .92em; color: var(--v3-muted); white-space: nowrap; }
.v3 .v3-example li svg { inline-size: 1.05em; block-size: 1.05em; flex: none; }
.v3 .v3-example li > span { display: inline-flex; align-items: center; gap: .3em; flex: none; }
.v3 .v3-example li .v3-route { inline-size: .9em; block-size: .9em; }
.v3 .v3-example__cost { font-weight: 700; color: var(--v3-text); }

/* The text keeps clear of the card: at most the width left of it. */
.v3 .v3-tripless .v3-hero { min-block-size: 18rem; }
.v3 .v3-tripless .v3-hero__inner { padding-block: 2.5rem; }
.v3 .v3-tripless .v3-hero__inner > * { max-inline-size: 36rem; }
.v3 .v3-tripless .v3-hero h1 { font-size: clamp(1.75rem, 3.2vw, 2.125rem); }
.v3 .v3-tripless .v3-hero__sub { max-inline-size: 34rem; }
.v3 .v3-tripless .v3-hero__cta { margin-block-end: 0; }

/* Narrower than the design: the photo becomes a band above the text,
   at its own ratio, so nothing overlaps. */
@container (max-width: 82rem) {
    .v3 .v3-tripless .v3-hero { min-block-size: 0; }
    .v3 .v3-hero__media {
        position: relative; inset: auto;
        inline-size: 100%; min-block-size: 9rem;
    }
    .v3 .v3-hero__media > img { -webkit-mask-image: none; mask-image: none; }
    .v3 .v3-tripless .v3-hero__inner { padding-block: 1.5rem 1.75rem; }
}

/* ---- "everything for your trip": the welcome page's steps, with icons */
.v3 .v3-band {
    padding: 1.5rem 1.5rem 1.75rem; text-align: center;
    background: var(--v3-hero-fade);
}
.v3 .v3-band h2 { margin: 0; font-size: 1.5rem; font-weight: 800; }
.v3 .v3-steps--icons { max-inline-size: 60rem; margin-inline: auto; }
.v3 .v3-steps--icons li { display: flex; flex-direction: column; align-items: center; }
.v3 .v3-steps--icons h3 { margin-block-start: .8rem; font-size: 1rem; }
.v3 .v3-steps--icons p { max-inline-size: 13rem; font-size: .875rem; }
/* The dashed line runs from one icon to the next (centre to centre, less
   the tiles); the grid gap is 1rem. */
.v3 .v3-steps--icons li:not(:last-child)::after {
    inset-block-start: 1.55rem;
    inset-inline-start: calc(50% + 2.3rem);
    inset-inline-end: calc(-50% - 1rem + 2.3rem);
}

/* ============================================================
   `/travel` with trips — "My travels" (request 205, task 0227)
   Same shell arrangement as the no-trips page above (`.v3` on the
   page's wrapper, `main.v3-bleed`). Buttons, cards, icon tiles and
   `.v3-link` are the shared ones; below is only what is new.
   ============================================================ */
.v3 .v3-mytrips { container-type: inline-size; }

/* ---- hero ------------------------------------------------------
   The photo is the header's whole background (task 0242) and runs
   down behind the stat cards. It is an arbitrary picture, so the
   text does not sit on it directly: a scrim lies between the two,
   and scrim and text colour are tokens picked to hold 4.5:1 over
   any pixel. The focus ring takes the text colour for the same
   reason. Buttons keep their own surface. */
.v3 .v3-mt-hero { position: relative; overflow: hidden; background: var(--v3-hero-fade); color: var(--v3-on-hero); }
.v3 .v3-mt-hero__photo {
    position: absolute; inset: 0; inline-size: 100%; block-size: 100%;
    object-fit: cover; object-position: center;
}
/* A photo with its subject on one side and no text or landmark in it (the contacts
   one, task 0266) is mirrored under RTL, so the title keeps the empty side. */
[dir="rtl"] .v3 .v3-mt-hero__photo--mirror { transform: scaleX(-1); }
.v3 .v3-mt-hero::after { content: ""; position: absolute; inset: 0; background: var(--v3-hero-scrim); }
.v3 .v3-mt-hero :focus-visible { outline-color: var(--v3-on-hero); }
.v3 .v3-mt-hero__inner {
    position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: flex-start;
    justify-content: space-between; gap: 1rem 1.5rem;
    padding-block: 1.75rem 6.5rem;
}
.v3 .v3-mt-hero h1 { margin: 0 0 .35rem; font-size: clamp(1.75rem, 3vw, 2.25rem); font-weight: 800; line-height: 1.15; color: inherit; }
.v3 .v3-mt-hero__sub { font-size: 1.0625rem; }
.v3 .v3-mt-hero__actions { display: flex; flex-wrap: wrap; gap: .6rem; }

/* ---- body --------------------------------------------------- */
.v3 .v3-mt-body { position: relative; display: flex; flex-direction: column; gap: 1.25rem; padding-block-end: 2rem; }

/* stat cards: pulled up over the hero's lower edge */
.v3 .v3-stats {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1rem;
    margin-block-start: -5rem;
}
.v3 .v3-stat {
    position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: .15rem;
    block-size: 100%; padding: 1.1rem 1.2rem 1.2rem;
    color: var(--v3-text); text-decoration: none;
}
.v3 .v3-stat:hover { border-color: var(--v3-primary); }
.v3 .v3-stat .v3-icon { margin-block-end: .55rem; }
.v3 .v3-stat__go { position: absolute; inset-block-start: 1.4rem; inset-inline-end: 1.1rem; inline-size: 1.1rem; block-size: 1.1rem; color: var(--v3-muted); }
.v3 .v3-stat__name { font-size: 1.0625rem; font-weight: 700; overflow-wrap: anywhere; }
.v3 .v3-stat__n { font-size: 1.6rem; font-weight: 800; line-height: 1.2; }
.v3 .v3-stat__desc { font-size: .875rem; line-height: 1.45; color: var(--v3-muted); }

.v3 .v3-mt-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(16rem, 24rem); gap: 1.25rem; align-items: stretch; }

/* recent trips */
.v3 .v3-recent { padding: 1.25rem; }
.v3 .v3-recent__head { display: flex; align-items: flex-start; gap: .75rem; margin-block-end: 1rem; }
.v3 .v3-recent__head > div { flex: 1; }
.v3 .v3-recent__head h2 { margin: 0 0 .15rem; font-size: 1.25rem; font-weight: 800; }
.v3 .v3-recent__head p { font-size: .9375rem; color: var(--v3-muted); }
.v3 .v3-recent__mark { color: var(--v3-link); }
.v3 .v3-recent__mark svg { inline-size: 1.9rem; block-size: 1.9rem; }
/* min(): at 200% text on a phone 12.5rem is wider than the screen (task 0235). */
.v3 .v3-tcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(var(--v3-trip-photo-w), 100%), 1fr)); gap: 1rem; }
.v3 .v3-tcard {
    position: relative; display: flex; flex-direction: column; overflow: hidden;
    background: var(--v3-card); border: 1px solid var(--v3-border); border-radius: .8rem;
}
.v3 .v3-tcard:hover { border-color: var(--v3-primary); }
/* The name is the link; it stretches over the card so the whole card opens the trip.
   The focus ring moves to the card, where it can be seen whole. */
.v3 .v3-tcard__name a { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; color: inherit; text-decoration: none; }
.v3 .v3-tcard__name a::after { content: ""; position: absolute; inset: 0; }
.v3 .v3-tcard__name a:focus-visible { outline: none; }
.v3 .v3-tcard:has(a:focus-visible) { outline: 3px solid var(--v3-primary); outline-offset: 2px; }
.v3 .v3-tcard__media { position: relative; }
.v3 .v3-tcard__media img { display: block; inline-size: 100%; block-size: var(--v3-trip-photo-h); object-fit: cover; }
.v3 .v3-badge {
    position: absolute; inset-block-start: .5rem; inset-inline-end: .5rem;
    padding: .15rem .6rem; border-radius: 999px;
    background: var(--v3-card); color: var(--v3-text); font-size: .75rem; font-weight: 700;
}
:root[data-mono] .v3 .v3-badge { border: 1px solid var(--v3-border); }
.v3 .v3-tcard__body { display: flex; flex-direction: column; flex: 1; padding: .75rem .85rem .8rem; }
.v3 .v3-tcard__name { display: flex; align-items: center; gap: .45rem; margin: 0 0 .45rem; font-size: 1rem; font-weight: 700; }
.v3 .v3-tcard__go { inline-size: 1rem; block-size: 1rem; color: var(--v3-muted); flex: none; }
/* The trip's countries under its name (task 0228). Above the card's stretched link,
   so each flag's tooltip (the country name) shows on hover. */
.v3 .v3-flags {
    position: relative; z-index: 1; display: flex; flex-wrap: wrap; gap: .3rem;
    margin: -.15rem 0 .5rem; padding: 0; list-style: none;
}
.v3 .v3-flags li { display: flex; }
.v3 .v3-flags .v3-flag { inline-size: 1.4rem; block-size: 1.05rem; object-fit: cover; }
.v3 .v3-tcard__meta { display: flex; flex-direction: column; gap: .3rem; font-size: .8125rem; color: var(--v3-muted); }
.v3 .v3-tcard__meta li { display: flex; align-items: center; gap: .5rem; }
.v3 .v3-tcard__meta svg { inline-size: .95rem; block-size: .95rem; flex: none; }
.v3 .v3-tcard__foot {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: .4rem .75rem;
    margin: auto 0 0; padding-block-start: .65rem;
    border-block-start: 1px solid var(--v3-border);
}
.v3 .v3-tcard__meta { margin-block-end: .75rem; }
.v3 .v3-tcard__foot dt { display: flex; align-items: center; gap: .25rem; font-size: .6875rem; color: var(--v3-muted); }
.v3 .v3-tcard__foot dt svg { inline-size: .8rem; block-size: .8rem; flex: none; }
.v3 .v3-tcard__foot dd { margin: .1rem 0 0; font-size: .8125rem; font-weight: 700; white-space: nowrap; }

/* at a glance */
.v3 .v3-glance { position: relative; overflow: hidden; padding: 1.25rem 1.25rem 9rem; }
.v3 .v3-glance h2 { margin: 0 0 1rem; font-size: 1.25rem; font-weight: 800; }
.v3 .v3-glance__body { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-around; gap: 1rem; }
/* The ring is decoration around one number, not a chart: it is always whole. */
.v3 .v3-ring {
    display: grid; place-items: center; align-content: center;
    inline-size: 8.5rem; block-size: 8.5rem; border-radius: 50%;
    border: .7rem solid var(--v3-primary); border-block-end-color: var(--v3-teal-fg);
    background: var(--v3-card);
}
.v3 .v3-ring__icon { inline-size: 1.5rem; block-size: 1.5rem; color: var(--v3-link); }
.v3 .v3-ring__n { font-size: 1.75rem; font-weight: 800; line-height: 1.1; }
.v3 .v3-ring__label { font-size: .875rem; color: var(--v3-muted); }
.v3 .v3-glance__list { display: flex; flex-direction: column; gap: .6rem; }
.v3 .v3-glance__list li { display: flex; align-items: center; gap: .7rem; }
.v3 .v3-glance__list strong { min-inline-size: 1.8rem; font-size: 1.05rem; }
.v3 .v3-glance__list span:last-child { color: var(--v3-muted); font-size: .875rem; }
.v3 .v3-glance__photo {
    position: absolute; inset-inline: 0; inset-block-end: 0; inline-size: 100%; block-size: 8.5rem;
    object-fit: cover; object-position: right bottom;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 55%);
            mask-image: linear-gradient(to bottom, transparent 0%, #000 55%);
}

/* next adventure */
.v3 .v3-next {
    display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.25rem;
    padding: 1rem 1.25rem; background: var(--v3-hero-fade);
}
.v3 .v3-next__text { flex: 1 1 18rem; }
.v3 .v3-next h2 { margin: 0 0 .15rem; font-size: 1.125rem; font-weight: 800; }
.v3 .v3-next p { font-size: .9375rem; color: var(--v3-muted); }

/* ---- narrower than the design ---------------------------------- */
@container (max-width: 80rem) {
    .v3 .v3-stats { grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); }
}
@container (max-width: 66rem) {
    .v3 .v3-mt-grid { grid-template-columns: minmax(0, 1fr); }
}
@container (max-width: 40rem) {
    .v3 .v3-mt-hero__inner { padding-block: 1.25rem 5.5rem; }
    .v3 .v3-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .75rem; }
    .v3 .v3-stat { padding: .9rem; }
    .v3 .v3-next .v3-btn { flex: 1 1 100%; white-space: normal; text-align: center; }
}

/* ============================================================
   The trips list, `/travel/trips` (task 0230)
   No design image: built from the pieces above — the "My travels"
   hero without its stat-card overlap, the card, the icon set.
   Same shell arrangement (`.v3` on the page wrapper, `main.v3-bleed`).
   ============================================================ */
.v3 .v3-tlpage { container-type: inline-size; }
.v3 .v3-mt-hero--plain .v3-mt-hero__inner { padding-block: 1.75rem; }
.v3 .v3-tl-body { padding-block: 1.25rem 2rem; }
.v3 .v3-tl { padding: 1.25rem; }

/* head: title, count, filters */
.v3 .v3-tl__head { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; margin-block-end: 1rem; }
.v3 .v3-tl__head h2 { margin: 0; font-size: 1.25rem; font-weight: 800; }
.v3 .v3-count {
    min-inline-size: 1.9rem; padding: .1rem .55rem; border-radius: 999px; text-align: center;
    background: var(--v3-blue-bg); color: var(--v3-blue-fg); font-size: .8125rem; font-weight: 700;
}
:root[data-mono] .v3 .v3-count { border: 1px solid var(--v3-border); }
.v3 .v3-tl__filters { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-inline-start: auto; }
.v3 .v3-select {
    min-block-size: 2.25rem; padding: .3rem .8rem; border-radius: 999px;
    border: 1px solid var(--v3-input-border); background: var(--v3-input-bg); color: var(--v3-text);
    font: inherit; font-size: .875rem;
}
.v3 .v3-select[data-active="true"] { border-color: var(--v3-primary); background: var(--v3-blue-bg); color: var(--v3-blue-fg); font-weight: 600; }
.v3 .v3-seg {
    display: inline-flex; flex-wrap: wrap; gap: .2rem; padding: .2rem;
    border: 1px solid var(--v3-border); border-radius: 999px; background: var(--v3-card-2);
}
.v3 .v3-seg button {
    min-block-size: 1.9rem; padding: .25rem .85rem; border: 0; border-radius: 999px;
    background: transparent; color: var(--v3-text); font: inherit; font-size: .875rem; font-weight: 600; cursor: pointer;
}
.v3 .v3-seg button:hover { background: var(--v3-blue-bg); }
/* Pressed is told by fill AND by aria-pressed; in monochrome the fill is ink. */
.v3 .v3-seg button[aria-pressed="true"] { background: var(--v3-primary); color: var(--v3-on-primary); }

/* rows */
.v3 .v3-tl__list { display: flex; flex-direction: column; gap: .75rem; }
.v3 .v3-tl-row {
    position: relative;
    display: grid; grid-template-columns: var(--v3-trip-photo-w) minmax(0, 1fr) auto; align-items: start; gap: 1rem;
    padding: .6rem; border: 1px solid var(--v3-border); border-radius: .8rem; background: var(--v3-card);
}
.v3 .v3-tl-row:hover { border-color: var(--v3-primary); }
/* `display: grid` outranks the UA's `[hidden]` rule (the 0131c trap). */
.v3 .v3-tl-row[hidden] { display: none; }
.v3 .v3-tl-row__photo { display: block; inline-size: 100%; block-size: var(--v3-trip-photo-h); object-fit: cover; border-radius: .6rem; }
.v3 .v3-tl-row__body { display: flex; flex-direction: column; gap: .45rem; min-inline-size: 0; padding-block: .15rem; }
.v3 .v3-tl-row__name { margin: 0; font-size: 1.0625rem; font-weight: 700; }
.v3 .v3-tl-row__name a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
.v3 .v3-tl-row__name a:hover { color: var(--v3-link); text-decoration: underline; }
/* The whole row opens the trip (story 207): the name link is stretched over the row,
   as on the recent-trip cards, so there is still one tab stop per trip. The focus
   ring moves to the row, where it can be seen whole. Edit / delete and the avatars
   (whose tooltip names the person) sit above the stretched link. */
.v3 .v3-tl-row--link .v3-tl-row__name a::after { content: ""; position: absolute; inset: 0; border-radius: .8rem; }
.v3 .v3-tl-row--link:hover .v3-tl-row__name a { color: var(--v3-link); text-decoration: underline; }
.v3 .v3-tl-row--link .v3-tl-row__name a:focus-visible { outline: none; }
.v3 .v3-tl-row--link:has(.v3-tl-row__name a:focus-visible) { outline: 3px solid var(--v3-primary); outline-offset: 2px; }
.v3 .v3-tl-row--link .v3-tl-row__actions,
.v3 .v3-tl-row--link .v3-avatars { position: relative; z-index: 1; }
.v3 .v3-tl-row__when { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .9rem; font-size: .875rem; color: var(--v3-muted); }
.v3 .v3-tl-row__dates { display: inline-flex; align-items: center; gap: .35rem; }
.v3 .v3-tl-row__dates svg, .v3 .v3-tl-row__metric svg { inline-size: .95rem; block-size: .95rem; flex: none; }

/* text tags: the words carry the meaning, the tint only groups them */
.v3 .v3-tag { padding: .1rem .6rem; border-radius: 999px; font-size: .75rem; font-weight: 700; }
.v3 .v3-tag--upcoming  { background: var(--v3-blue-bg);   color: var(--v3-blue-fg); }
.v3 .v3-tag--ongoing   { background: var(--v3-green-bg);  color: var(--v3-green-fg); }
.v3 .v3-tag--past      { background: var(--v3-card-2);    color: var(--v3-muted); border: 1px solid var(--v3-border); }
.v3 .v3-tag--shared    { background: var(--v3-violet-bg); color: var(--v3-violet-fg); }
.v3 .v3-tag--shared-out { background: var(--v3-teal-bg);  color: var(--v3-teal-fg); }
:root[data-mono] .v3 .v3-tag { border: 1px solid var(--v3-border); }

/* country badges: flag + name */
.v3 .v3-cbadges { display: flex; flex-wrap: wrap; gap: .35rem; }
.v3 .v3-cbadge {
    display: inline-flex; align-items: center; gap: .4rem; padding: .15rem .6rem .15rem .35rem;
    border: 1px solid var(--v3-border); border-radius: 999px; background: var(--v3-card-2);
    font-size: .8125rem; font-weight: 600;
}
.v3 .v3-cbadge .v3-flag { inline-size: 1.25rem; block-size: .95rem; object-fit: cover; border-radius: 3px; }

/* companions and counts */
.v3 .v3-tl-row__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1.1rem; font-size: .8125rem; color: var(--v3-muted); }
.v3 .v3-tl-row__metric { display: inline-flex; align-items: center; gap: .3rem; }
.v3 .v3-tl-row__metric b { color: var(--v3-text); }
.v3 .v3-avatars { display: inline-flex; padding-inline-start: .35rem; }
.v3 .v3-avatars > span:not(.sr-only) {
    display: inline-grid; place-items: center; inline-size: 1.9rem; block-size: 1.9rem;
    margin-inline-start: -.35rem; border-radius: 50%; border: 2px solid var(--v3-card);
    background: var(--v3-violet-bg); color: var(--v3-violet-fg); font-size: .6875rem; font-weight: 700;
}
:root[data-mono] .v3 .v3-avatars > span:not(.sr-only) { border-color: var(--v3-border); }

/* edit / delete */
.v3 .v3-tl-row__actions { display: flex; gap: .4rem; }
.v3 .v3-iconbtn {
    display: inline-grid; place-items: center; inline-size: 2.25rem; block-size: 2.25rem;
    border: 1px solid var(--v3-border); border-radius: 50%; background: var(--v3-card); color: var(--v3-muted); cursor: pointer;
}
.v3 .v3-iconbtn svg { inline-size: 1.05rem; block-size: 1.05rem; }
.v3 .v3-iconbtn:hover { border-color: var(--v3-primary); color: var(--v3-link); }
/* Edit and delete are filled at rest on every v3 page, not only under the pointer
   (tasks 0268–0270). Colour is not what says "edit" or "delete" — the glyph and the
   button's name do — so monochrome, where both fills are ink, loses nothing. */
.v3 .v3-iconbtn--edit { background: var(--v3-edit-fill); border-color: var(--v3-edit-border); color: var(--v3-on-edit); }
.v3 .v3-iconbtn--edit:hover { background: var(--v3-edit-fill-hover); border-color: var(--v3-edit-border); color: var(--v3-on-edit); }
.v3 .v3-iconbtn--danger { background: var(--v3-danger-fill); border-color: var(--v3-danger-fill); color: var(--v3-on-danger); }
.v3 .v3-iconbtn--danger:hover { background: var(--v3-danger-fill-hover); border-color: var(--v3-danger-fill-hover); color: var(--v3-on-danger); }

.v3 .v3-tl__empty { padding: 2rem 1rem; text-align: center; }
.v3 .v3-tl__empty h3 { margin: 0 0 .3rem; font-size: 1.0625rem; }
.v3 .v3-tl__empty p { color: var(--v3-muted); }

@container (max-width: 40rem) {
    .v3 .v3-tl { padding: 1rem .75rem; }
    /* `position`: a `.label-filter--fit` dropdown hangs its panel from the whole row
       on a phone (task 0278d; the rule is in `components_v2.css`). */
    .v3 .v3-tl__filters { margin-inline-start: 0; position: relative; }
    /* One column: the photo becomes a band on top, so the text keeps the full width
       (at 200% text a side-by-side photo left it a few words wide). */
    .v3 .v3-tl-row { grid-template-columns: minmax(0, 1fr); gap: .6rem; }
    .v3 .v3-tl-row__actions { justify-content: flex-end; }
    /* Nothing may be wider than the row: long names and labels wrap. */
    .v3 .v3-mt-hero__actions .v3-btn { white-space: normal; text-align: start; }
    .v3 .v3-cbadge { max-inline-size: 100%; }
    .v3 .v3-avatars { flex-wrap: wrap; row-gap: .25rem; }
}

/* Two trips to a row, the two of one height (story 221: tasks 0262–0264); rows may
   differ. The card: photo with the status on its end corner, the text beside it, then
   the countries and under them the travelers, across the full width and right under
   the photo — a shorter card's spare space is at its bottom. The photo comes after
   the text in the source; the grid areas put it first. Where half the width is too
   narrow for a photo beside the text, the card stacks. A phone has one card per row. */
.v3 .v3-tl__list--pairs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.v3 .v3-tl__list--pairs .v3-tl-row {
    grid-template-rows: auto auto; align-content: start;
    grid-template-areas: "media body actions" "foot foot foot";
}
.v3 .v3-tl__list--pairs .v3-tl-row__media { grid-area: media; position: relative; }
/* The photo now follows the link in the source and is positioned (for the badge), so it
   would cover the stretched link: lift the link over it. Edit / delete and the avatars
   come later still, at the same level, and stay on top. */
.v3 .v3-tl__list--pairs .v3-tl-row__name a::after { z-index: 1; }
.v3 .v3-tl__list--pairs .v3-tl-row__body { grid-area: body; }
.v3 .v3-tl__list--pairs .v3-tl-row__actions { grid-area: actions; }
.v3 .v3-tl__list--pairs .v3-tl-row__foot {
    grid-area: foot; display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; min-inline-size: 0;
}
.v3 .v3-tl__list--pairs .v3-tl-row__metric { font-size: .8125rem; }
@container (max-width: 70rem) {
    .v3 .v3-tl__list--pairs .v3-tl-row {
        grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; gap: .6rem;
        grid-template-areas: "media" "body" "foot" "actions";
    }
    .v3 .v3-tl__list--pairs .v3-tl-row__actions { justify-content: flex-end; }
}
@container (max-width: 40rem) {
    .v3 .v3-tl__list--pairs { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   "All countries I have visited", `/travel/visited-countries` (task 0234)
   No design image: the trips list's hero, card, count and row above,
   with the welcome page's numbered mark. A country row has no actions,
   so its grid drops the third column. Only what is new is below.
   ============================================================ */
.v3 .v3-tl-row--noact { grid-template-columns: var(--v3-trip-photo-w) minmax(0, 1fr); }
.v3 .v3-vc-name { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.v3 .v3-vc-name .v3-steps__num { inline-size: 1.75rem; block-size: 1.75rem; font-size: .8125rem; flex: none; }
.v3 .v3-vc-name .v3-flag { inline-size: 1.4rem; block-size: 1.05rem; object-fit: cover; }
.v3 .v3-vc-name > span:last-child { min-inline-size: 0; overflow-wrap: anywhere; }

/* the trips that took the user there: name (link), then its dates */
.v3 .v3-vc-trips { display: flex; flex-direction: column; gap: .35rem; }
.v3 .v3-vc-trips li {
    display: flex; flex-wrap: wrap; align-items: center; gap: .15rem .9rem;
    padding: .4rem .7rem; border-radius: .6rem; background: var(--v3-card-2);
    font-size: .875rem; color: var(--v3-muted);
}
:root[data-mono] .v3 .v3-vc-trips li { border: 1px solid var(--v3-border); }
.v3 .v3-vc-trips a,
.v3 .v3-vc-trips__name { font-weight: 600; color: var(--v3-link); overflow-wrap: anywhere; }
.v3 .v3-vc-trips__name { color: var(--v3-text); }
/* Underlined: in monochrome the link colour equals the text colour. */
.v3 .v3-vc-trips a { text-decoration: underline; text-underline-offset: .15em; }

@container (max-width: 40rem) {
    .v3 .v3-tl-row--noact { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   Cities, flights and stays, `/travel/cities|flights|stays` (task 0236)
   Cities is built like the visited countries above. Flights and stays
   stay tables (one flight / stay per row, compared by column) in the
   same card; below 40rem each row becomes a small card of
   `label: value` lines, as the v2 lists do. The filters are the shared
   `_list_filters` partial with the v3 select; its panel keeps the v2
   mechanics and takes v3 colours here.
   ============================================================ */
.v3 .v3-table { inline-size: 100%; border-collapse: collapse; font-size: .875rem; }
.v3 .v3-table th {
    padding: .5rem .75rem; text-align: start; vertical-align: bottom;
    font-size: .8125rem; font-weight: 700; color: var(--v3-muted);
    border-block-end: 1px solid var(--v3-border);
}
.v3 .v3-table td { padding: .7rem .75rem; vertical-align: top; border-block-end: 1px solid var(--v3-border); }
.v3 .v3-table tbody tr:last-child td { border-block-end: 0; }
.v3 .v3-table tbody tr:hover td { background: var(--v3-card-2); }
/* The filters hide rows with `hidden`; the phone layout below sets `display`. */
.v3 .v3-table tr[hidden] { display: none; }
.v3 .v3-table__no { inline-size: 1%; white-space: nowrap; }
.v3 .v3-table .v3-steps__num { inline-size: 1.75rem; block-size: 1.75rem; font-size: .8125rem; }
.v3 .v3-table__cell { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .3rem .5rem; }
.v3 .v3-table__sub { color: var(--v3-muted); font-size: .8125rem; }
.v3 .v3-table__strong { font-weight: 600; }
.v3 .v3-table__arrow { inline-size: .9rem; block-size: .9rem; color: var(--v3-muted); flex: none; }
/* Underlined: in monochrome the link colour equals the text colour. */
.v3 .v3-table__link { color: var(--v3-link); font-weight: 600; text-decoration: underline; text-underline-offset: .15em; overflow-wrap: anywhere; }

/* flight numbers and airport codes */
.v3 .v3-code {
    display: inline-block; padding: .05rem .45rem; border-radius: .35rem;
    background: var(--v3-blue-bg); color: var(--v3-blue-fg);
    font-size: .8125rem; font-weight: 700; letter-spacing: .03em; white-space: nowrap;
}
.v3 .v3-code--plain { background: var(--v3-card-2); color: var(--v3-text); border: 1px solid var(--v3-border); }
:root[data-mono] .v3 .v3-code { border: 1px solid var(--v3-border); }

/* who flew / stayed */
.v3 .v3-chips { display: flex; flex-wrap: wrap; gap: .25rem; margin-block-start: .4rem; }
.v3 .v3-chips > span,
.v3 .v3-chips > li > span {
    padding: .05rem .5rem; border-radius: 999px;
    background: var(--v3-violet-bg); color: var(--v3-violet-fg); font-size: .75rem; font-weight: 600;
}
:root[data-mono] .v3 .v3-chips > span,
:root[data-mono] .v3 .v3-chips > li > span { border: 1px solid var(--v3-border); }

/* the traveller filter's panel, in v3 colours */
.v3 .v3-tl__filters .v3-select { display: inline-flex; align-items: center; gap: .4rem; cursor: pointer; }
.v3 .v3-tl__filters .v3-select[aria-expanded="true"] { border-color: var(--v3-primary); background: var(--v3-blue-bg); color: var(--v3-blue-fg); }
.v3 .label-filter__panel { background: var(--v3-card); border-color: var(--v3-border); box-shadow: var(--v3-shadow); }
.v3 .label-filter__panel .check { color: var(--v3-text); }
.v3 .label-filter__foot { background: var(--v3-card); border-color: var(--v3-border); }

@container (max-width: 40rem) {
    .v3 .v3-table thead { display: none; }
    .v3 .v3-table, .v3 .v3-table tbody, .v3 .v3-table tr, .v3 .v3-table td { display: block; }
    .v3 .v3-table tr { margin-block-end: .6rem; border: 1px solid var(--v3-border); border-radius: .8rem; overflow: hidden; }
    .v3 .v3-table tr[hidden] { display: none; }
    .v3 .v3-table td { padding: .45rem .75rem; }
    .v3 .v3-table tbody tr:last-child td { border-block-end: 1px solid var(--v3-border); }
    .v3 .v3-table tr td:last-child { border-block-end: 0; }
    .v3 .v3-table__no { inline-size: auto; }
    .v3 .v3-table td[data-label]::before {
        content: attr(data-label); display: block; margin-block-end: .15rem;
        font-size: .75rem; font-weight: 700; color: var(--v3-muted);
    }
}

/* ============================================================
   The single-trip dashboard, `/travel/{slug}` (task 0238)
   No design image: the list pages' plain hero with the trip's
   country picture, the "My travels" stat cards as the area cards,
   and v3 cards. Two columns for the owner (the "Shared with" card
   on the side), one for anyone else — as in v2 (request 201).
   ============================================================ */
.v3 .v3-btn--sm { min-block-size: 2.1rem; padding: .3rem .85rem; font-size: .8125rem; }

/* hero facts: dates, nights, origin, currency */
.v3 .v3-td-facts { display: flex; flex-wrap: wrap; gap: .4rem 1.25rem; margin-block-start: .35rem; font-size: .9375rem; }
.v3 .v3-td-facts li { display: inline-flex; align-items: center; gap: .4rem; }
.v3 .v3-td-facts svg { inline-size: 1rem; block-size: 1rem; flex: none; }

.v3 .v3-td-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.v3 .v3-td-main, .v3 .v3-td-region { display: flex; flex-direction: column; gap: 1.25rem; min-inline-size: 0; }

/* area cards: the "My travels" stat card, in a grid of their own */
.v3 .v3-td-areas { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(9.5rem, 100%), 1fr)); gap: .9rem; }
.v3 .v3-td-areas .v3-stat { padding: .9rem 1rem 1rem; }
.v3 .v3-td-areas .v3-stat .v3-icon { margin-block-end: .45rem; }
.v3 .v3-td-areas .v3-stat__go { inset-block-start: 1.2rem; }
.v3 .v3-td-areas .v3-stat__name { font-size: .9375rem; }
.v3 .v3-td-areas .v3-stat__n { font-size: 1.4rem; }

/* cards */
.v3 .v3-td-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); gap: 1.25rem; }
.v3 .v3-td-card { padding: 1.1rem 1.25rem 1.25rem; min-inline-size: 0; }
.v3 .v3-td-card__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; margin-block-end: .8rem; }
.v3 .v3-td-card__head h2 { margin: 0; font-size: 1.125rem; font-weight: 800; }
.v3 .v3-td-card__empty { color: var(--v3-muted); font-size: .875rem; }
.v3 .v3-td-card__note { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; color: var(--v3-muted); font-size: .875rem; }
.v3 .v3-td-note-icon, .v3 .v3-td-go { inline-size: 1rem; block-size: 1rem; flex: none; }
.v3 .v3-td-card .v3-chips { margin: 0; }
.v3 .v3-td-card .v3-chips > li > span { display: inline-block; padding: .2rem .7rem; font-size: .8125rem; }

/* expenses: totals by status, then categories beside the pie */
.v3 .v3-td-totals { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); gap: .75rem; margin: 0 0 .8rem; }
.v3 .v3-td-totals > div { padding: .7rem .85rem; border: 1px solid var(--v3-border); border-radius: .75rem; background: var(--v3-card-2); }
.v3 .v3-td-totals dt { margin-block-end: .35rem; font-size: .8125rem; font-weight: 700; color: var(--v3-muted); }
.v3 .v3-td-totals dd { margin: 0; font-size: 1.05rem; font-weight: 800; overflow-wrap: anywhere; }
.v3 .v3-td-totals > .v3-td-totals__grand { background: var(--v3-blue-bg); border-color: var(--v3-primary); }
.v3 .v3-td-totals__grand dt, .v3 .v3-td-totals__grand dd { color: var(--v3-blue-fg); }
.v3 .v3-td-cats { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; margin-block-start: 1rem; }
.v3 .v3-td-cats--pie { grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); align-items: start; }
.v3 .v3-td-catlist li {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: .15rem 1rem; padding-block: .45rem;
    border-block-end: 1px solid var(--v3-border); font-size: .875rem;
}
.v3 .v3-td-catlist li:last-child { border-block-end: 0; }
.v3 .v3-td-catlist li > span:first-child { min-inline-size: 0; overflow-wrap: anywhere; }
.v3 .v3-td-catlist__val { font-weight: 700; white-space: nowrap; margin-inline-start: auto; }
.v3 .v3-td-pie__legend li > span:nth-child(2) { min-inline-size: 0; overflow-wrap: anywhere; }
.v3 .v3-td-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.25rem; }
.v3 .v3-td-pie__chart { inline-size: 8.5rem; block-size: 8.5rem; border-radius: 50%; flex: none; box-shadow: 0 0 0 1px var(--v3-border); }
.v3 .v3-td-pie__legend { display: flex; flex-direction: column; gap: .35rem; font-size: .8125rem; min-inline-size: 0; }
.v3 .v3-td-pie__legend li { display: flex; align-items: center; gap: .45rem; }
.v3 .v3-td-pie__swatch { inline-size: .8rem; block-size: .8rem; border-radius: 3px; flex: none; }
.v3 .v3-td-pie__pct { margin-inline-start: auto; padding-inline-start: .5rem; font-weight: 700; }

/* the owner's "Shared with" card: styled as the cards of `/shared` (`.v3-sharewith`,
   task 0292); here only the rule above its button, as above a shared card's actions */
.v3 .v3-td-side__action { margin-block-start: 8px; padding-block-start: 8px; border-block-start: 1px solid var(--v3-border); }
/* In a narrow column at 200% text the label must wrap, not widen the card. */
.v3 .v3-td-side__action .v3-btn { max-inline-size: 100%; white-space: normal; text-align: start; }

@media (min-width: 961px) {
    .v3 .v3-td-grid--split { grid-template-columns: minmax(0, 7fr) minmax(0, 3fr); }
}
/* Lighter titles above the phone breakpoint (story 0211, task 0245) — the dashboard
   only: the trip pages share `.v3-td-card` and `/travel` shares `.v3-stat`. */
@media (min-width: 641px) {
    .v3 .v3-td .v3-td-card__head h2 { font-weight: 700; }
    .v3 .v3-td .v3-td-areas .v3-stat__name { font-weight: 600; }
}

/* ============================================================
   Trip pages — flights, accommodation, rental cars, expenses, plan,
   map, itinerary — and the companions page (tasks 0240a–0240i)
   No design image: the plain hero with the trip's country picture
   (`travel/_trip_hero_v3.php`), then v3 cards. The page wrapper is
   `.v3-tp`; cards and their heads are the dashboard's (`.v3-td-card`).

   Some v2 components stay as they are built — the wide tables
   (expenses, plan, itinerary, mileage) with their phone layouts, the
   segment cards, badges, inputs. They keep their v2 rules and take
   v3 colours here: inside `.v3-tp` the v2 tokens they read point at
   v3's. No v2 rule is edited, and nothing outside the wrapper (the
   shell, the dialogs) is touched.
   ============================================================ */
.v3 .v3-tp {
    --text: var(--v3-text); --text-muted: var(--v3-muted); --text-dim: var(--v3-muted);
    --stroke: var(--v3-border); --stroke-2: var(--v3-input-border); --hairline: var(--v3-border);
    --glass: var(--v3-card); --glass-2: var(--v3-card-2); --panel: var(--v3-card);
    --sunken: var(--v3-card-2); --tint: var(--v3-card-2); --row-hover: var(--v3-card-2);
    --brand-400: var(--v3-primary); --on-brand: var(--v3-on-primary);
    --input-bg: var(--v3-input-bg); --input-bg-focus: var(--v3-input-bg);
    --radius: 1rem; --radius-sm: .6rem;
}
.v3 .v3-tp__body, .v3 .v3-tp__region { display: flex; flex-direction: column; gap: 1.25rem; min-inline-size: 0; }
/* Underlined: in monochrome the link colour equals the text colour. */
.v3 .v3-tp-trip { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: .15em; }
.v3 .v3-tp-trip:hover { text-decoration-thickness: .14em; }

/* a card that a link elsewhere lands on (`#stay-12`, `#booking-3`, `#car-4`) */
.v3 .v3-td-card[id] { scroll-margin-block-start: 5rem; }
.v3 .v3-td-card[id]:target { outline: 3px solid var(--v3-primary); outline-offset: 2px; }

/* card head: what it is on one side, its actions on the other */
.v3 .v3-tp-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: .6rem 1rem; }
.v3 .v3-tp-head > div:first-child { flex: 1 1 16rem; min-inline-size: 0; }
.v3 .v3-tp-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .6rem; margin: 0 0 .3rem; font-size: 1.125rem; font-weight: 800; overflow-wrap: anywhere; }
.v3 .v3-tp-title a { color: inherit; text-decoration: underline; text-underline-offset: .15em; }
.v3 .v3-tp-title a:hover { color: var(--v3-link); }
.v3 .v3-tp-title__kind { font-size: .875rem; font-weight: 600; color: var(--v3-muted); letter-spacing: 0; }
.v3 .v3-tp-meta { color: var(--v3-muted); font-size: .875rem; overflow-wrap: anywhere; }
.v3 .v3-tp-meta + .v3-tp-meta { margin-block-start: .2rem; }
.v3 .v3-tp-hint { color: var(--v3-muted); font-size: .875rem; }
.v3 .v3-tp-total { margin-block-start: 1rem; font-size: .9375rem; }
.v3 .v3-tp-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
/* The "show contact" badge (task 0278c) is the shared `.contact-badge`; here it takes v3's blue. */
.v3 .contact-badge { --cb-card: var(--v3-primary); --cb-disc: var(--v3-on-primary); }
.v3 .v3-tp-actions form { display: inline-flex; margin: 0; }
.v3 .v3-tp-actions--end { justify-content: flex-end; margin-block-start: .9rem; }

/* buttons this section adds */
.v3 .v3-btn--danger { background: var(--v3-card); color: var(--v3-danger); border-color: var(--v3-danger); }
.v3 .v3-btn--danger:hover { background: var(--v3-danger); color: var(--v3-card); }
/* A toggle that is on, and the link of the view being shown: told by the fill AND by
   `aria-pressed` / `aria-current`; in monochrome the fill is ink. */
.v3 .v3-btn[aria-pressed="true"],
.v3 .v3-btn[aria-current="true"],
.v3 .map-day-btn.is-active { background: var(--v3-primary); color: var(--v3-on-primary); border-color: var(--v3-primary); }
/* `travel.js` puts the v2 `.btn--ghost` on the day-subtotals toggle; it must not repaint it. */
.v3 .v3-btn--outline.btn--ghost { background: var(--v3-card); color: var(--v3-link); border-color: var(--v3-primary); }
.v3 .v3-btn--outline.btn--ghost[aria-pressed="true"] { background: var(--v3-primary); color: var(--v3-on-primary); }
.v3 .v3-tag--warn { background: var(--v3-amber-bg); color: var(--v3-amber-fg); }
.v3 a.v3-tag { text-decoration: underline; }

/* an inner card: passengers, segments, services, rooms */
.v3 .v3-tp-sub { margin-block-start: 1rem; padding: .85rem 1rem; border: 1px solid var(--v3-border); border-radius: .8rem; background: var(--v3-card-2); }
.v3 .v3-tp-sub__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; margin-block-end: .6rem; }
.v3 .v3-tp-sub__head h2, .v3 .v3-tp-sub__head h3 { margin: 0; font-size: .9375rem; font-weight: 800; }

/* rows inside a card: one room, one passenger, one service */
.v3 .v3-tp-rows > li {
    display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .75rem; padding-block: .5rem;
    border-block-end: 1px solid var(--v3-border); font-size: .875rem;
}
.v3 .v3-tp-rows > li:last-child { border-block-end: 0; padding-block-end: 0; }
.v3 .v3-tp-rows__name { font-weight: 700; overflow-wrap: anywhere; }
.v3 .v3-tp-rows .v3-tp-actions { margin-inline-start: auto; }

/* filters above a table */
.v3 .v3-tp-filters { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.v3 .v3-tp-filters .check { color: var(--v3-text); }

/* the kept v2 pieces, fitted to a v3 card */
/* `position`: a visually-hidden label inside a wide table is absolutely placed; without
   a positioned scroll box it escapes the box and widens the page. */
.v3 .v3-tp .table-wrap { margin-block-end: 0; position: relative; }
.v3 .v3-tp .seg-card { border-radius: .8rem; }
.v3 .v3-tp table .v3-btn { min-block-size: 1.9rem; padding: .2rem .7rem; font-size: .8125rem; border-width: 1px; white-space: normal; }
.v3 .v3-tp table .v3-iconbtn { inline-size: 2rem; block-size: 2rem; }
.v3 .v3-tp table .v3-tp-actions { justify-content: flex-end; }
.v3 .v3-tp .share-box { margin-block: 0; }
.v3 .v3-tp .share-box__summary { font-weight: 800; }
.v3 .v3-tp #travel-map { border-radius: 1rem; }

@container (max-width: 40rem) {
    /* Nothing may be wider than its card: long button labels wrap. */
    .v3 .v3-tp .v3-btn { white-space: normal; text-align: start; }
    .v3 .v3-tp-actions { max-inline-size: 100%; }
    .v3 .v3-tp-sub { padding: .75rem; }
}
/* A one-word title ("Accommodation") at 200% text on a phone must break, not be cut off. */
.v3 .v3-tp .v3-mt-hero__inner > div { min-inline-size: 0; max-inline-size: 100%; }
.v3 .v3-tp .v3-mt-hero h1 { overflow-wrap: anywhere; }
.v3 .v3-tp-kv, .v3 .v3-tp-kv dd { margin: 0; }
.v3 .v3-td-card > .v3-tp-hint { margin-block-end: .6rem; }
.v3 .v3-tp .plan-actions .v3-tp-actions { flex-wrap: nowrap; }
.v3 .v3-tp-mapdays { margin-block-end: .9rem; }
.v3 .v3-tp-itin .table-wrap { margin-block-end: .6rem; }

/* companions (task 0240i): the lists' table, with the person as each row's header */
.v3 .v3-table tbody th {
    padding: .7rem .75rem; vertical-align: top; font-size: .875rem; font-weight: 400; color: var(--v3-text);
}
.v3 .v3-table tbody tr:last-child th { border-block-end: 0; }
.v3 .v3-table tbody tr:hover th { background: var(--v3-card-2); }
.v3 .v3-cmp-who .v3-avatars { vertical-align: middle; }
.v3 .v3-cmp-who__text { display: inline-flex; flex-direction: column; gap: .2rem; vertical-align: middle; margin-inline-start: .5rem; max-inline-size: calc(100% - 3rem); }
.v3 .v3-cmp-note { font-style: italic; }
.v3 .v3-cmp-email { overflow-wrap: anywhere; }
.v3 .v3-tl__empty h2 { margin: 0 0 .3rem; font-size: 1.0625rem; }
@container (max-width: 40rem) {
    .v3 .v3-table tbody th { display: block; padding: .6rem .75rem; }
}
.v3 [data-companions] .v3-tp-actions { justify-content: flex-start; }

/* ============================================================
   My contacts, `/contacts` (task 0241)
   The companions list above — plain hero, one card, the lists' table
   with the person as each row's header. The group chips and the pager
   stay v2 components (`contacts.js` clones the first into a v2 dialog
   and builds the second), in v3 colours through `.v3-tp`.
   ============================================================ */
.v3 .v3-ct-search { inline-size: 12rem; max-inline-size: 100%; }
.v3 .v3-ct-search::placeholder { color: var(--v3-muted); opacity: 1; }
.v3 .v3-ct-field { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .25rem .45rem; }
.v3 .v3-ct-field label { font-size: .875rem; font-weight: 600; color: var(--v3-muted); }

/* A click anywhere on the row opens the contact card; the name is the keyboard way in. */
.v3 .v3-ct tbody tr { cursor: pointer; }
.v3 .v3-ct td[data-cell="actions"] { cursor: default; }
.v3 .v3-ct__open {
    padding: 0; border: 0; background: none; color: inherit; font: inherit; font-weight: 600;
    text-align: start; cursor: pointer; overflow-wrap: anywhere;
}
.v3 .v3-ct__open:hover .contact-name { color: var(--v3-link); text-decoration: underline; }
/* From the start edge, so the pencils line up when a row (the user's own) has no delete. */
.v3 .v3-tp table.v3-ct .v3-tp-actions { justify-content: flex-start; }
.v3 .v3-ct td { overflow-wrap: anywhere; }
.v3 .v3-ct .chips span { white-space: normal; }
.v3 .v3-ct th.v3-cmp-who, .v3 .v3-ct td { vertical-align: middle; }

/* the pager: the v2 buttons as v3 pills; the current page is told by the fill AND by
   `aria-current` (in monochrome the fill is ink) */
.v3 .v3-tl .pager { margin-block: 1rem 0; }
.v3 .pager__page, .v3 .pager__step { border-radius: 999px; }
.v3 .pager__page[aria-current="page"] { background: var(--v3-primary); border-color: var(--v3-primary); color: var(--v3-on-primary); }

/* Constant column widths, so the table does not shift between pages or as the filter
   changes which names are shown. The actions column holds its six buttons on one row. */
@container (min-width: 40.01rem) {
    .v3 .v3-ct { table-layout: fixed; }
    .v3 .v3-ct th:nth-child(1) { inline-size: 42%; }
    .v3 .v3-ct th:nth-child(3) { inline-size: 16.5rem; }
}
@container (max-width: 40rem) {
    .v3 .v3-ct-search { inline-size: 100%; }
    .v3 .v3-tl__filters > [role="search"] { flex: 1 1 100%; }
}

/* ============================================================
   My contacts groups, `/contacts/groups` (task 0267, story 222)
   The contacts list's hero and card; inside it each group is a card,
   at most four to a row: name and actions (in the end corner) on the
   first row, the number of contacts on the second, then the contacts
   as a trip card shows its travelers.
   ============================================================ */
.v3 .v3-grp-list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .75rem; }
.v3 .v3-grp {
    display: flex; flex-direction: column; gap: .55rem; min-inline-size: 0;
    padding: .9rem; border: 1px solid var(--v3-border); border-radius: .8rem; background: var(--v3-card);
}
.v3 .v3-grp__top { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; }
.v3 .v3-grp__name { min-inline-size: 0; margin: 0; font-size: 1.0625rem; font-weight: 700; overflow-wrap: anywhere; }
.v3 .v3-grp__top .v3-tp-actions { flex: none; flex-wrap: nowrap; }
.v3 .v3-grp__top .v3-iconbtn { inline-size: 2rem; block-size: 2rem; }
.v3 .v3-grp__builtin { flex: none; font-size: .8125rem; color: var(--v3-muted); }
.v3 .v3-grp__count { display: inline-flex; align-items: center; gap: .35rem; font-size: .875rem; color: var(--v3-muted); }
.v3 .v3-grp__count svg { inline-size: .95rem; block-size: .95rem; flex: none; }
.v3 .v3-grp .v3-avatars { flex-wrap: wrap; row-gap: .25rem; }
@container (max-width: 70rem) { .v3 .v3-grp-list { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container (max-width: 52rem) { .v3 .v3-grp-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container (max-width: 40rem) { .v3 .v3-grp-list { grid-template-columns: minmax(0, 1fr); } }

/* ============================================================
   Shared objects, `/shared` (task 0285, story 229)
   The contacts pages' hero and card; inside it each object is the
   flight segment's card (`.seg-card` in `.seg-list`, kept v2 rules).
   Only what an object has and a segment has not is styled here.
   ============================================================ */
/* A segment's row is as tall as the page's tallest card; here one object may be held by
   one person and the next by ten, so a row is only as tall as its own cards. */
.v3 .v3-shr-list { grid-auto-rows: auto; margin-block-start: 0; }
/* Head (task 0286): the section's badge, then the name — beside it when both fit one
   line, else on a line of its own, where a long name wraps. */
.v3 .v3-shr__head { justify-content: flex-start; align-items: center; gap: 6px 10px; }
.v3 .v3-shr__name { flex: 0 1 auto; min-inline-size: 0; max-inline-size: 100%; font-size: 1.0625rem; font-weight: 700; overflow-wrap: anywhere; }
/* No underline until hover or focus (task 0288); the name is still the link. */
.v3 .v3-shr__name a { color: inherit; text-decoration: none; text-underline-offset: .15em; }
.v3 .v3-shr__name a:hover, .v3 .v3-shr__name a:focus-visible { color: var(--v3-link); text-decoration: underline; }
/* Where a segment has its route: under a rule, taking the card's spare height so the
   row of actions sits on the card's floor. */
.v3 .v3-shr__people { flex: 1 0 auto; margin-block-start: 8px; padding-block-start: 8px; border-block-start: 1px solid var(--v3-border); }
/* The size of a segment's date (`.seg-card__date`, task 0288). */
/* `.v3-sharewith` wraps the shared "Shared with" block wherever it takes this look: a
   card here, and the trip dashboard's side card (task 0292). */
.v3 .v3-sharewith .share-manage__title { color: var(--v3-muted); }
.v3 .v3-sharewith .share-manage__name { flex: 1 1 6rem; min-inline-size: 0; color: var(--v3-text); font-size: .8rem; }
/* A name that opens the contact card (task 0289): a button that reads as the name,
   underlined on hover and focus as the contacts list's is. */
.v3 .v3-sharewith .share-manage__open { padding: 0; border: 0; background: none; font-family: inherit; font-weight: 600; text-align: start; cursor: pointer; overflow-wrap: anywhere; }
.v3 .v3-sharewith .share-manage__open:hover .contact-name,
.v3 .v3-sharewith .share-manage__open:focus-visible .contact-name { color: var(--v3-link); text-decoration: underline; }
.v3 .v3-sharewith .share-manage__title::after { content: ":"; }
/* The people (task 0286): no card around each, a rule between them. */
.v3 .v3-sharewith .share-manage__list { gap: 0; }
/* One line (task 0288): the name at the start, the permission and the button at the end.
   Where they do not fit — a phone, 200% text — the pair drops under the name, still at the end. */
.v3 .v3-sharewith .share-manage__row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 8px 0; border: 0; border-radius: 0; background: none; }
.v3 .v3-sharewith .share-manage__controls { margin-inline-start: auto; justify-content: flex-end; }
.v3 .v3-sharewith .share-manage__result { flex: 1 0 100%; }
.v3 .v3-sharewith .share-manage__row + .share-manage__row { border-block-start: 1px solid var(--v3-border); }
.v3 .v3-sharewith .share-manage__row:last-child { padding-block-end: 0; }
/* The permission is still the select that changes it, shown as the airport badge. */
.v3 .v3-sharewith .share-manage__role { flex: none; min-inline-size: 4.6em; padding-block: 3px; margin-block: 0; font-family: inherit; text-align: start; cursor: pointer; }
/* "Stop sharing" at three quarters of the small button: its text size and its padding. */
.v3 .v3-sharewith [data-share-revoke] { padding: 3.75px 7.5px; font-size: .6375rem; }

/* Flights or accommodation page with nothing on it (requests 214, 224): the two ways
   forward, a card each, side by side — a heading and its buttons, centred. A lone card
   (a trip that is over has no search) takes the row. */
.v3 .v3-tp-empty { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 1rem; }
.v3 .v3-tp-empty__card { display: flex; flex-direction: column; align-items: center; gap: .9rem; padding: 2rem 1rem; text-align: center; }
.v3 .v3-tp-empty__title { margin: 0; font-size: 1.0625rem; }
.v3 .v3-tp-empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; }
.v3 .v3-tp-empty .v3-btn { white-space: normal; text-align: center; }
@media (max-width: 640px) {
    .v3 .v3-tp-empty { grid-auto-flow: row; }
}

/* Search flights page (request 214). The page's form keeps its v2 pieces; here are
   only the v3 card's padding and the v3 buttons' wrapping. The page's two columns
   are the trip dashboard's `.v3-td-grid--split` (story 214, update 1). */
.v3 .fs-block { padding: 1.25rem; }
.v3 .fs-recent a { color: var(--v3-link); }
/* Import a booking page (tasks 0256a–b): the links of its "nothing found" note. */
.v3 .bi-none a { color: var(--v3-link); }
/* The delete button beside a saved search: the size it has in a table row, so a
   line of small text is not spaced out by its own button. */
.v3 .fs-recent .v3-iconbtn { inline-size: 2rem; block-size: 2rem; }
.v3 .fs-links .v3-btn, .v3 .fs-actions .v3-btn, .v3 .fs-legs-actions .v3-btn { white-space: normal; text-align: center; }

/* ---- "How it works" (task 0303c) ------------------------------ */
.v3 .v3-hiw { display: flex; flex-direction: column; gap: 2.25rem; padding-block: 2rem 2.5rem; }
.v3 .v3-hiw h2 { margin: 0 0 .7rem; font-size: 1.5rem; font-weight: 800; }
.v3 .v3-hiw__text { max-inline-size: 48rem; }
.v3 .v3-hiw__text p, .v3 p.v3-hiw__text { font-size: 1rem; line-height: 1.6; color: var(--v3-text); }
.v3 .v3-hiw__text p + p { margin-block-start: .7rem; }
.v3 p.v3-hiw__text { margin-block-end: 1.1rem; }
.v3 .v3-hiw__steps {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); gap: 1rem;
}
.v3 .v3-hiw__step { padding: 1.1rem 1.2rem 1.3rem; }
.v3 .v3-hiw__step h3 { margin: .7rem 0 .35rem; font-size: 1.0625rem; font-weight: 700; }
.v3 .v3-hiw__step p { font-size: .9375rem; line-height: 1.55; color: var(--v3-text); }
/* Three cards side by side from the first width that holds them; one column before. */
.v3 .v3-hiw__examples { grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); }
.v3 .v3-hiw__about { margin-block-start: .8rem; font-size: .9375rem; line-height: 1.5; color: var(--v3-text); }
.v3 .v3-hiw__pages {
    list-style: none; margin: .7rem 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: .35rem 1rem; font-size: .9375rem;
}
.v3 .v3-hiw__pages a { color: var(--v3-link); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
