  /* ===== Self-hosted fonts (Open Sans + Young Serif) =====
     Bundled locally in /fonts so the app contacts no external font CDN.
     latin + latin-ext subsets included so accented place names render. */
  @font-face {
    font-family: 'Open Sans';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/opensans-400i-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/opensans-400i-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/opensans-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/opensans-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/opensans-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/opensans-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/opensans-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/opensans-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/opensans-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/opensans-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  /* Note: headings intentionally use the system serif (Georgia → serif).
     The original "Young Serif" Fontshare link never resolved, so the app has
     always rendered headings in Georgia — we keep that look and don't bundle
     Young Serif. The font-family stacks below still list 'Young Serif' first,
     so a real Young Serif file can be dropped in later if ever desired. */

  :root {
    --white: #FFFFFF;
    --green: #004745;
    --green-deep: #00302e;
    --green-soft: #e8f1f0;
    --pink: #d81159;
    --pink-deep: #a00d42;
    --pink-soft: #fdeaf0;
    /* Amber for "late but actionable" — booking timeline milestones whose
       ideal window has passed but the trip hasn't started yet. Warm caution
       tone, not failure red. */
    --amber: #b45309;
    --amber-soft: #fef3c7;
    /* True destructive red — used ONLY for irreversible destructive confirms
       (delete trip, remove family member, replace with backup, etc.). Pink is
       reserved for primary actions; mixing them creates UX confusion. */
    --danger: #DC2626;
    --danger-soft: #fee2e2;
    --ink: #004745;
    --muted: #4a6b69;
    --border: 1.5px solid var(--green);
  }

  * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
  /* (Removed Build 20) --kb-height CSS variable and scroll-margin rules.
     See matching JS removal note. Modal now stays in its rest position
     regardless of keyboard state — keyboard overlays content, user scrolls
     internally to reach hidden inputs. */
  html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
  /* Build 28: lock the document so iOS can't scroll the body. Scrolling moves
     to .app (the next rule). This is the standard architecture for native-
     feeling mobile web apps — fixes iOS's "fixed elements drift during scroll"
     bug because body never scrolls in the first place. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
  }
  body {
    font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--white);
    color: var(--ink);
    line-height: 1.55;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
  }
  /* Native-app polish: when running inside Capacitor (iOS/Android app builds),
     suppress the long-press text-selection magnifier + Copy/Lookup callout on
     UI chrome. The web version (gotravelkeeper.com) stays untouched.
     Inputs/textareas/contenteditable explicitly opt back in so users can still
     edit and copy what they've typed. */
  body.platform-native {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }
  body.platform-native input,
  body.platform-native textarea,
  body.platform-native [contenteditable="true"] {
    -webkit-user-select: text;
    user-select: text;
    -webkit-touch-callout: default;
  }
  h1, h2, h3, h4, .serif {
    font-family: 'Young Serif', Georgia, serif;
    font-weight: 400;
    color: var(--green);
  }
  em { font-style: italic; color: var(--pink); }
  button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
  a { color: var(--green); }

  /* ============ APP SHELL ============ */
  /* Build 28: .app is now THE scroll container (body is locked above). Centered
     in the viewport at max 640px wide on larger screens; takes the full
     viewport on mobile. Content inside scrolls within .app. Sticky/fixed
     elements inside it position relative to this real scroll container, not
     iOS's buggy body-scroll context. */
  .app {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    max-width: 640px;
    background: var(--white);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: env(safe-area-inset-bottom);
  }
  /* On screens wider than the app (iPad, desktop web), frame the centered white
     column on a soft tinted backdrop so it reads as an intentional layout
     rather than a phone app floating in white margins. */
  @media (min-width: 760px) {
    body { background: var(--green-soft); }
    /* Wider column on iPad/desktop so the content uses the space instead of
       floating as a narrow phone-width strip. */
    .app { max-width: 860px; box-shadow: 0 0 50px rgba(0, 71, 69, 0.12); }
  }

  .view { display: none; animation: viewFade 0.18s ease; }
  .view.active { display: block; }

  /* ============ ONBOARDING (first-launch experience) ============ */
  #view-onboarding { position: relative; min-height: 100dvh; }
  .onboard-shell {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    padding: env(safe-area-inset-top) 1.5rem env(safe-area-inset-bottom);
    background: var(--white);
    position: relative;
  }
  .onboard-skip {
    position: absolute;
    top: calc(0.85rem + env(safe-area-inset-top));
    right: 1.25rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    z-index: 10;
  }
  .onboard-skip:hover, .onboard-skip:active { color: var(--green); }
  .onboard-dots {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-top: calc(1.4rem + env(safe-area-inset-top));
  }
  .onboard-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--green-soft);
    transition: background 0.2s ease, transform 0.2s ease;
  }
  .onboard-dot.active {
    background: var(--pink);
    transform: scale(1.35);
  }
  .onboard-step {
    display: none;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem 0;
    animation: viewFade 0.25s ease;
  }
  .onboard-step.active { display: flex; }
  .onboard-mark {
    /* Travel Keeper line-art icon — shows only on the first onboarding slide.
       Transparent PNG with pink luggage + plane silhouette. */
    width: 96px;
    height: 96px;
    margin: 0 auto 1.5rem;
    background-image: url('icons/icon-mark.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
  }
  .onboard-step h1 {
    font-family: 'Young Serif', Georgia, serif;
    font-weight: 400;
    font-size: clamp(2rem, 8vw, 2.6rem);
    color: var(--green);
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin-bottom: 0.9rem;
    max-width: 14em;
  }
  .onboard-step h1 em { color: var(--pink); font-style: italic; }
  .onboard-step p {
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1.5;
    max-width: 28em;
    margin: 0 auto 0.85rem;
  }
  .onboard-step p em { color: var(--pink); font-style: italic; }
  /* Tight paragraph variant: line-breaks read like one flowing paragraph
     with no extra space between lines. */
  .onboard-step p.onboard-tight { line-height: 1.5; }
  /* Last paragraph gets the bigger bottom margin to separate from the
     CTA button. Earlier paragraphs only have a small gap between them. */
  .onboard-step p:last-of-type { margin-bottom: 2.25rem; }
  .onboard-next { min-width: 12rem; }
  .onboard-email-form {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    width: 100%;
    max-width: 22rem;
    margin: 0 auto 0.5rem;
  }
  .onboard-email-form input {
    padding: 0.85rem 1rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    text-align: center;
  }
  .onboard-email-form input::placeholder { color: var(--muted); }
  .onboard-email-form input:focus { border-color: var(--pink); }
  .onboard-email-status {
    font-size: 0.85rem;
    color: var(--green);
    text-align: center;
    margin-bottom: 1rem;
    min-height: 1.2em;
  }
  .onboard-email-status.error { color: var(--pink-deep); }
  .onboard-finish-link {
    font-size: 0.85rem;
    color: var(--muted);
    text-decoration: none;
    border-bottom: 1px dashed var(--muted);
    padding-bottom: 1px;
  }
  .onboard-finish-link:hover, .onboard-finish-link:active { color: var(--green); border-color: var(--green); }
  /* Pure opacity fade — no vertical translation. The earlier translateY(6px)
     created the appearance of a "page jump" inside iOS/Android WebViews.
     Web users barely noticed it but native users perceived it as harsh. */
  @keyframes viewFade { from { opacity: 0; } to { opacity: 1; } }

  /* ============ TOP BAR ============ */
  .topbar {
    padding: 0.15rem 1.25rem 0.2rem;
    border-bottom: var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    /* Build 33: padding tightened even further (was 0.25rem/0.3rem,
       now 0.15rem/0.2rem). The .tabs' sticky `top` is updated below to
       match this new topbar height so there's no visible gap between
       them while scrolling. */
    position: sticky;
    top: 0;
    background: var(--white);
    z-index: 100;
    padding-top: calc(0.15rem + env(safe-area-inset-top));
  }
  /* iPad/desktop: more breathing room above the wordmark so the header doesn't
     look smushed against the top. Placed after the base rule so it wins. */
  @media (min-width: 760px) {
    .topbar { padding-top: calc(1.4rem + env(safe-area-inset-top)); }
  }
  .brand {
    font-family: 'Futura', 'Futura PT', 'Jost', 'Trebuchet MS', 'Century Gothic', sans-serif;
    font-weight: 500;
    font-size: 1.05rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--green);
    /* Build 30: remove typographic line-height padding so the topbar can be
       even tighter. The wordmark renders at its exact font-size height. */
    line-height: 1;
  }
  .topbar-meta {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .topbar-meta::before {
    content: '';
    width: 6px; height: 6px;
    background: var(--pink);
    border-radius: 50%;
  }
  .backbtn {
    font-size: 0.82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--green);
    /* Build 41: bumped font + padding slightly so the back-navigation button
       has more presence — users were missing it. Still small enough that the
       topbar doesn't grow noticeably taller than the home wordmark. */
    padding: 0.35rem 0.85rem;
    line-height: 1;
    border: var(--border);
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: background 0.18s, color 0.18s;
    -webkit-tap-highlight-color: transparent;
  }
  /* Green flash during press, back to white when released. :hover scoped
     to real pointer devices so it doesn't stick on iOS after a tap. */
  .backbtn:active {
    background: var(--green);
    color: var(--white);
  }
  @media (hover: hover) {
    .backbtn:hover {
      background: var(--green);
      color: var(--white);
    }
  }
  .backbtn .arr { font-size: 0.9rem; }

  /* ============ HOME — HERO ============ */
  .home-hero {
    padding: 1.25rem 1.25rem 1rem;
    border-bottom: var(--border);
  }
  .kicker {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    color: var(--pink);
    margin-bottom: 0.55rem;
    display: flex;
    align-items: center;
    gap: 0.65rem;
  }
  .kicker::before {
    content: '';
    width: 24px; height: 1.5px;
    background: var(--pink);
  }
  .home-hero h1 {
    font-size: clamp(1.75rem, 6vw, 2.25rem);
    line-height: 1.08;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
  }
  .home-hero p {
    color: var(--muted);
    font-size: 0.95rem;
    max-width: 34em;
  }
  /* Compact hero variant: applied when user has 1+ trips. Hides the body paragraph
     and tightens vertical padding so trip cards rise on the screen for returning users. */
  .home-hero.compact {
    padding: 1rem 1.25rem 0.85rem;
  }
  .home-hero.compact h1 {
    margin-bottom: 0;
  }
  .home-hero.compact #home-hero-body {
    display: none;
  }

  /* ============ EMAIL CAPTURE BANNER ============ */
  .email-bar {
    display: none;
    margin: 1rem 1.25rem 0;
    padding: 1rem 1.1rem;
    border: var(--border);
    background: var(--green-soft);
    box-shadow: 5px 5px 0 var(--green);
    position: relative;
  }
  .email-bar.shown { display: block; animation: slideIn 0.4s ease; }
  @keyframes slideIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
  .email-bar-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--green);
    margin-bottom: 0.25rem;
    line-height: 1.2;
  }
  .email-bar-title em { color: var(--pink); }
  .email-bar-body {
    font-size: 0.85rem;
    color: var(--muted);
    margin-bottom: 0.75rem;
  }
  .email-bar form {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .email-bar input {
    flex: 1 1 180px;
    padding: 0.65rem 0.75rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .email-bar input:focus { border-color: var(--pink); }
  .email-bar button.submit {
    padding: 0.65rem 1rem;
    background: var(--green);
    color: var(--white);
    font-weight: 700;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    border: var(--border);
    transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
  }
  .email-bar button.submit:hover { background: var(--pink); border-color: var(--pink); transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--green); }
  .email-bar button.submit:disabled { opacity: 0.6; cursor: wait; }
  /* Backup nudge: flat (no green offset shadow box) + clean pink hover, no jump. */
  .backup-bar { box-shadow: none; }
  .email-bar.backup-bar button.submit:hover { background: var(--pink); border-color: var(--pink); transform: none; box-shadow: none; }
  .email-bar-body a { color: var(--pink); font-weight: 600; text-decoration: underline; }
  .email-bar .close {
    position: absolute;
    top: 0.5rem; right: 0.6rem;
    font-size: 1.25rem;
    color: var(--muted);
    line-height: 1;
    padding: 0.25rem 0.5rem;
  }
  .email-bar .close:hover { color: var(--pink); }
  .email-bar .status {
    font-size: 0.8rem;
    color: var(--green);
    margin-top: 0.5rem;
    font-style: italic;
    display: none;
  }
  .email-bar .status.shown { display: block; }
  .email-bar .status.error { color: var(--pink-deep); }

  /* ============ TRIPS SECTION ============ */
  .trips-section {
    padding: 1.25rem 1.25rem 0.75rem;
  }
  .section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 1.25rem;
    gap: 1rem;
  }
  .section-header h2 {
    font-size: 1.35rem;
    letter-spacing: -0.005em;
  }
  .section-header .count {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--muted);
  }

  /* Cards / Year toggle */
  .trips-view-toggle {
    display: flex;
    gap: 0;
    border: var(--border);
    background: var(--white);
  }
  .view-toggle {
    padding: 0.45rem 0.95rem;
    background: transparent;
    border: none;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--muted);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
  }
  .view-toggle.active {
    background: var(--green);
    color: var(--white);
  }
  .view-toggle:not(.active):hover { color: var(--green); }

  /* ============ YEAR VIEW ============ */
  .year-view {
    margin-bottom: 1.5rem;
  }

  .year-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 0 1.25rem;
    border-bottom: var(--border);
    margin-bottom: 1.5rem;
  }
  .year-nav-btn {
    padding: 0.5rem 0.85rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    min-width: 2.5rem;
  }
  .year-nav-btn:hover:not(:disabled) {
    background: var(--green);
    color: var(--white);
  }
  .year-nav-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
  }
  .year-nav-label {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 2rem;
    color: var(--green);
    flex: 1;
    text-align: center;
  }

  /* Year stats block */
  .year-stats {
    margin-bottom: 1.75rem;
    padding: 1.4rem 1.25rem;
    border: var(--border);
    background: var(--white);
    box-shadow: 6px 6px 0 var(--green);
  }
  .year-stats-summary {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--pink);
    margin-bottom: 1rem;
  }
  .year-stats-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.9rem 1.25rem;
  }
  .year-stat {
    border-top: 1px solid var(--border-color, #E8EBE9);
    padding-top: 0.55rem;
  }
  .year-stat-label {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    margin-bottom: 0.2rem;
  }
  .year-stat-val {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.45rem;
    color: var(--green);
    line-height: 1.2;
  }
  /* Points-program stat values match the Costs totals card (pink-deep) */
  .year-stat.points .year-stat-val {
    color: var(--pink-deep);
  }
  /* Brag stats — "Saved with points/FNCs", "Credits used" — visually distinct from base stats.
     Pink accent to signal "this is a win," not "this is what you paid." */
  .year-stat.brag .year-stat-label {
    color: var(--green);
  }
  .year-stat.brag .year-stat-val {
    color: var(--pink);
    font-weight: 700;
  }
  .year-stat-secondary {
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.15rem;
    font-style: italic;
  }
  /* Divider between regular totals and brag stats in the year-stats block */
  .year-brag-divider {
    height: 0;
    border-top: 2px solid var(--pink-soft);
    margin: 0.85rem 0 0.55rem;
    position: relative;
  }
  .year-brag-divider::before {
    content: 'WHAT YOU SAVED';
    position: absolute;
    top: -0.55rem;
    left: 0;
    background: var(--white);
    padding-right: 0.6rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--pink);
  }

  /* Year trip rows */
  .year-trips {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  .year-trip-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.9rem;
    align-items: center;
    padding: 0.9rem 0;
    border-bottom: 1px solid var(--border-color, #E8EBE9);
    cursor: pointer;
    transition: background 0.12s;
  }
  .year-trip-row:last-child { border-bottom: none; }
  .year-trip-row:hover { background: var(--green-soft); }
  .year-trip-main {
    min-width: 0;
  }
  .year-trip-name {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--text);
    line-height: 1.25;
    margin-bottom: 0.18rem;
  }
  .year-trip-meta {
    font-size: 0.72rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 600;
  }
  .year-trip-meta .trip-status {
    color: var(--pink);
    margin-left: 0.4rem;
  }
  .year-trip-meta .trip-status.past { color: var(--muted); }
  .year-trip-costs {
    text-align: right;
    font-size: 0.78rem;
    color: var(--text);
    line-height: 1.4;
  }
  .year-trip-costs .cash {
    font-weight: 600;
  }
  .year-trip-costs .points {
    color: var(--pink-deep);
    font-size: 0.72rem;
  }
  .year-trip-costs .none {
    color: var(--muted);
    font-style: italic;
    font-size: 0.85rem;
  }
  .year-trip-arrow {
    color: var(--muted);
    margin-left: 0.4rem;
  }

  /* Year empty state */
  .year-empty {
    text-align: center;
    padding: 2rem 1.5rem;
    border: var(--border);
    background: var(--white);
    color: var(--muted);
    font-style: italic;
    margin-bottom: 1.5rem;
  }

  /* Empty state */
  .empty {
    border: var(--border);
    padding: 2rem 1.5rem;
    text-align: center;
    box-shadow: 8px 8px 0 var(--green);
    background: var(--white);
    margin-bottom: 1.5rem;
  }
  /* Smaller variant — used by wishlist empty state, similar proportions to
     .family-empty so the no-icon variant doesn't feel oversized. */
  .empty.empty-compact {
    padding: 1.75rem 1.4rem;
    box-shadow: 6px 6px 0 var(--green);
  }
  .empty-mark {
    /* Travel Keeper line-art icon thumbnail — anchors empty states with
       pink luggage + plane silhouette on transparent background. */
    width: 72px;
    height: 72px;
    margin: 0 auto 0.85rem;
    background-image: url('icons/icon-mark.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
  }
  .empty h3 {
    font-size: 1.3rem;
    margin-bottom: 0.6rem;
    line-height: 1.2;
  }
  .empty h3 em { color: var(--pink); }
  .empty p {
    color: var(--muted);
    font-size: 0.9rem;
    margin-bottom: 1.25rem;
    max-width: 28em;
    margin-left: auto;
    margin-right: auto;
  }
  /* Clickable empty-state headline — wraps the mark + h3 so users can tap the
     whole "Let's plan your first one →" area to start a new trip. */
  .empty-cta-trigger {
    display: block;
    width: 100%;
    padding: 0.25rem 0;
    text-align: center;
    transition: transform 0.15s ease, opacity 0.15s ease;
  }
  .empty-cta-trigger:hover { transform: scale(1.02); }
  .empty-cta-trigger:active { transform: scale(0.98); opacity: 0.85; }
  .empty-cta-trigger .empty-arrow {
    display: inline-block;
    color: var(--pink);
    margin-left: 0.25rem;
    transition: transform 0.15s ease;
  }
  .empty-cta-trigger:hover .empty-arrow { transform: translateX(4px); }

  /* Trip card list */
  .trip-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
  }

  .trip-card {
    border: var(--border);
    padding: 0.9rem 1.1rem 0.95rem;
    background: var(--white);
    box-shadow: 6px 6px 0 var(--green);
    text-align: left;
    width: 100%;
    position: relative;
    transition: transform 0.15s, box-shadow 0.15s;
    display: block;
  }
  .trip-card:hover, .trip-card:focus-visible {
    transform: translate(-2px, -2px);
    box-shadow: 8px 8px 0 var(--pink);
    outline: none;
  }
  .trip-card.past {
    box-shadow: 6px 6px 0 var(--muted);
    opacity: 0.85;
  }
  .trip-card.past:hover { box-shadow: 8px 8px 0 var(--green); }

  .trip-card-top {
    display: flex;
    gap: 0.85rem;
    align-items: flex-start;
    margin-bottom: 0.65rem;
  }
  .trip-mark {
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    border: var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.2rem;
    color: var(--green);
    background: var(--green-soft);
    letter-spacing: -0.02em;
  }
  .trip-mark.accent { background: var(--pink-soft); color: var(--pink-deep); }
  .trip-body { flex: 1; min-width: 0; }
  .trip-dest {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.3rem;
    color: var(--green);
    line-height: 1.1;
    margin-bottom: 0.25rem;
    word-wrap: break-word;
  }
  .trip-dates {
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
  }

  .trip-countdown {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding-top: 0.65rem;
    border-top: 1px dashed var(--green);
  }
  .trip-countdown-val {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.35rem;
    color: var(--pink);
    line-height: 1;
  }
  .trip-countdown.past .trip-countdown-val { color: var(--muted); }
  .trip-countdown-label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.14em;
  }

  .trip-card-menu {
    position: absolute;
    top: 0.1rem;
    right: 0.1rem;
    /* Minimum 44×44pt iOS HIG touch target. Padding pushes the visible
       glyph inward while keeping the tappable area large enough that small
       fingers don't miss. */
    min-width: 44px;
    min-height: 44px;
    padding: 0.6rem 0.7rem;
    color: var(--muted);
    font-size: 0.9rem;
    letter-spacing: 0.1em;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .trip-card-menu:hover { color: var(--pink); }

  /* Add trip button (sticky bottom action) */
  .add-trip-btn {
    display: block;
    width: 100%;
    margin-top: 1.25rem;
    padding: 1rem 1.1rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.05rem;
    text-align: left;
    position: relative;
    transition: background 0.18s, color 0.18s, box-shadow 0.15s, transform 0.15s;
    box-shadow: 5px 5px 0 var(--green);
  }
  .add-trip-btn::after {
    content: '+';
    position: absolute;
    right: 1.1rem; top: 50%;
    transform: translateY(-50%);
    font-size: 1.5rem;
    color: var(--pink);
    font-family: 'Open Sans', sans-serif;
    font-weight: 300;
    transition: transform 0.2s;
  }
  .add-trip-btn:hover {
    background: var(--green);
    color: var(--white);
    transform: translate(-2px, -2px);
    box-shadow: 7px 7px 0 var(--pink);
  }
  .add-trip-btn:hover::after { color: var(--white); transform: translateY(-50%) rotate(90deg); }

  /* Primary CTA button */
  .btn-primary {
    display: inline-block;
    padding: 0.9rem 1.4rem;
    background: var(--green);
    color: var(--white);
    font-weight: 700;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    border: var(--border);
    transition: background 0.15s, border-color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  /* Clean color swap on press/hover — no offset shadow box. :hover scoped to
     pointer devices so it doesn't stick after a tap on iOS. */
  .btn-primary:active { background: var(--pink); border-color: var(--pink); }
  @media (hover: hover) {
    .btn-primary:hover { background: var(--pink); border-color: var(--pink); }
  }
  .btn-secondary {
    display: inline-block;
    padding: 0.8rem 1.2rem;
    background: var(--white);
    color: var(--green);
    font-weight: 700;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    border: var(--border);
    transition: background 0.15s, color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  .btn-secondary:active { background: var(--green); color: var(--white); }
  @media (hover: hover) {
    .btn-secondary:hover { background: var(--green); color: var(--white); }
  }

  /* ============ MODAL ============ */
  .modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 71, 69, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 200;
    display: none;
    align-items: flex-end;
    justify-content: center;
    animation: backdropFade 0.25s ease;
  }
  @keyframes backdropFade { from { opacity: 0; } to { opacity: 1; } }
  .modal-backdrop.shown { display: flex; }
  @media (min-width: 600px) {
    .modal-backdrop { align-items: center; }
  }
  .modal {
    background: var(--white);
    border: var(--border);
    width: 100%;
    max-width: 540px;
    max-height: 92vh;
    max-height: 92dvh; /* dynamic viewport — shrinks when iOS keyboard appears */
    overflow-y: auto;
    /* Reserve space below focused inputs so scrollIntoView doesn't land them
       behind the iOS keyboard. 300px ≈ keyboard + accessory bar height. */
    scroll-padding-bottom: 300px;
    /* Soft drop shadow for every modal — no pink offset box (Megan: don't use
       the chunky pink offset shadow anywhere). Matches the brag/account/year
       modals that already opted into this. */
    box-shadow: 0 12px 44px rgba(0,71,69,0.22);
    padding: 1.75rem 1.5rem 1.5rem;
    position: relative;
    animation: modalSlide 0.3s cubic-bezier(.2,.8,.2,1);
  }
  @keyframes modalSlide { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
  @media (max-width: 599px) {
    .modal { border-bottom: none; }
    /* Build 21: extra bottom padding inside the modal so users can scroll
       any bottom-of-form input UP above the keyboard. Without this, content
       ends at the modal's bottom edge and there's nowhere to scroll to.
       280px ≈ standard iOS keyboard height + suggestion bar.
       Build 26: scoped to modals that actually contain inputs/textareas —
       confirmation dialogs (delete trip, remove family member) don't need it. */
    .modal:has(input, textarea) { padding-bottom: 280px; }
  }
  .modal h2 {
    font-size: 1.5rem;
    margin-bottom: 0.35rem;
    line-height: 1.15;
    padding-right: 2rem;
  }
  .modal .modal-sub {
    font-size: 0.88rem;
    color: var(--muted);
    margin-bottom: 1.4rem;
  }

  /* Soft hint nudging users to the Wishlist if they don't have firm dates yet.
     Sits right below the modal subtitle in the trip-create modal. */
  .wishlist-nudge {
    margin-top: -0.6rem;
    margin-bottom: 1.4rem;
    padding: 0.7rem 0.85rem;
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
    font-size: 0.82rem;
    color: var(--green);
    line-height: 1.5;
  }
  .wishlist-nudge-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--pink-deep);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
  }
  .wishlist-nudge-link:hover, .wishlist-nudge-link:focus-visible {
    color: var(--pink);
    outline: none;
  }
  .modal-close {
    position: absolute;
    top: 0.85rem; right: 0.95rem;
    font-size: 1.6rem;
    color: var(--muted);
    line-height: 1;
    padding: 0.25rem 0.55rem;
  }
  .modal-close:hover { color: var(--pink); }

  .form-field {
    margin-bottom: 1.1rem;
  }
  .form-field label {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--green);
    margin-bottom: 0.45rem;
  }
  /* Hint copy that lives below a field. Styled on the base class so that
     standalone hints (e.g. spanning a multi-field row) match hints that
     sit inside a single .form-field — both get the same small muted look.
     The .form-field-scoped rule below just adds the top margin since
     standalone hints often use their own inline margin tweaks. */
  .hint {
    font-size: 0.78rem;
    color: var(--muted);
  }
  .form-field .hint {
    margin-top: 0.3rem;
  }
  .form-field input[type="text"],
  .form-field input[type="email"],
  .form-field input[type="number"] {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .form-field input:focus { border-color: var(--pink); }
  /* Hide number input arrows for cleaner look (Safari/Chrome/Firefox) */
  .form-field input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
  }
  .form-field input[type="number"]::-webkit-outer-spin-button,
  .form-field input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }

  .date-field {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 0.95rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    text-align: left;
    display: flex;
    align-items: center;
    justify-content: space-between;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .date-field:hover, .date-field:focus-visible { border-color: var(--pink); box-shadow: 3px 3px 0 var(--pink); }
  .date-field .date-text.placeholder { color: var(--muted); font-style: italic; }
  .date-field .caret { color: var(--pink); font-size: 0.85rem; }

  /* Datepicker (reused pattern from Break Planner) */
  .datepicker {
    display: none;
    margin-top: 0.6rem;
    border: var(--border);
    background: var(--white);
    padding: 0.85rem;
    box-shadow: 4px 4px 0 var(--green);
  }
  .datepicker.open { display: block; animation: pickerFade 0.2s ease; }
  @keyframes pickerFade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
  .dp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.65rem;
  }
  .dp-nav {
    padding: 0.35rem 0.6rem;
    font-size: 0.9rem;
    color: var(--green);
    border: var(--border);
    transition: background 0.15s, color 0.15s;
  }
  .dp-nav:hover:not(:disabled) { background: var(--green); color: var(--white); }
  .dp-nav:disabled { opacity: 0.3; cursor: not-allowed; }
  .dp-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
  }
  .dp-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    margin-bottom: 0.35rem;
  }
  .dp-weekdays div {
    text-align: center;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--muted);
    padding: 0.3rem 0;
  }
  .dp-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
  }
  .dp-day {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: var(--green);
    border: 1px solid transparent;
    transition: all 0.1s;
  }
  .dp-day.muted { color: var(--muted); opacity: 0.35; }
  .dp-day.disabled { opacity: 0.25; cursor: not-allowed; }
  .dp-day:not(.disabled):not(.selected):hover { border-color: var(--green); color: var(--green-deep); }
  .dp-day.selected { background: var(--pink); color: var(--white); border-color: var(--pink); font-weight: 700; }
  .dp-day.today:not(.selected) { border-color: var(--pink); color: var(--pink); font-weight: 700; }

  .form-error {
    color: var(--pink-deep);
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
    padding: 0.65rem 0.85rem;
    font-size: 0.85rem;
    margin-top: 0.5rem;
    display: none;
  }
  .form-error.shown { display: block; }

  .modal-actions {
    display: flex;
    gap: 0.75rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--green-soft);
  }

  /* ----- Paste-to-import (Pro) ----- */
  .import-cta {
    display: block;
    width: 100%;
    margin-top: 0.6rem;
    padding: 0.7rem 1rem;
    background: var(--white);
    border: var(--border);
    color: var(--green);
    font: 700 0.95rem 'Open Sans', sans-serif;
    letter-spacing: 0.02em;
    cursor: pointer;
    text-align: center;
    transition: background 0.15s, color 0.15s;
  }
  .import-cta:hover { background: var(--green); color: var(--white); }
  /* Pink sparkle marking the import CTA as the premium feature. Inline SVG
     (not the ✨ emoji) so it's a crisp brand-pink glyph, sized to the text. */
  .cta-spark {
    width: 0.95em; height: 0.95em;
    margin-right: 0.42em;
    vertical-align: -0.12em;
    fill: var(--pink);
    display: inline-block;
  }
  /* Lock badge for non-Pro (mirrors the calendar tab) — signals it's a Pro
     feature and nudges signup; tapping still routes to the upgrade path.
     Pink padlock SVG (not the 🔒 emoji), same data-URI pattern as .lock-icon. */
  .import-cta.locked::after {
    content: '';
    display: inline-block;
    width: 0.95em; height: 0.95em;
    margin-left: 0.44em;
    vertical-align: -0.14em;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d81159' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='11' width='14' height='10' rx='1.5'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") no-repeat center / contain;
  }

  /* Smaller "Find my flights" trigger (id beats .btn-primary's sizing). */
  #import-parse {
    width: auto;
    padding: 0.5rem 1.15rem;
    font-size: 0.85rem;
    letter-spacing: 0.04em;
  }
  .import-scan-btn {
    display: block;
    width: 100%;
    margin: 0 0 0.85rem;
    padding: 0.7rem 1rem;
    background: var(--white);
    border: var(--border);
    color: var(--green);
    font: 700 0.92rem 'Open Sans', sans-serif;
    letter-spacing: 0.02em;
    cursor: pointer;
    text-align: center;
    transition: background 0.15s, color 0.15s;
  }
  /* Pink camera icon (not the 📷 emoji), same data-URI approach as the locks.
     A ::before survives the JS button-label resets during scanning. */
  .import-scan-btn::before {
    content: '';
    display: inline-block;
    width: 1.05em; height: 1.05em;
    margin-right: 0.45em;
    vertical-align: -0.2em;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d81159' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M4 8a2 2 0 0 1 2-2h2.4l1.3-2h4.6l1.3 2H18a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8z'/><circle cx='12' cy='13' r='3.5'/></svg>") no-repeat center / contain;
  }
  .import-scan-btn:hover { background: var(--green); color: var(--white); }
  .import-scan-btn:disabled { opacity: 0.6; cursor: default; }
  /* display:block above would otherwise defeat the hidden attribute */
  .import-scan-btn[hidden] { display: none; }

  .import-warnings {
    margin-top: 0.9rem;
    padding: 0.6rem 0.8rem;
    background: #fff4f6;
    border: 1px solid var(--pink);
    color: var(--pink);
    font-size: 0.9rem;
    line-height: 1.4;
  }
  .import-warnings div + div { margin-top: 0.3rem; }

  .import-results { margin-top: 0.3rem; }
  .import-found {
    margin: 1rem 0 0.4rem;
    font: 600 0.95rem 'Open Sans', sans-serif;
    color: var(--green);
  }
  .import-card {
    border: var(--border);
    background: var(--white);
    padding: 0.7rem 0.8rem;
    margin-top: 0.6rem;
  }
  .import-card-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
  }
  .import-card-head .import-include {
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--pink);
    flex: 0 0 auto;
  }
  .import-tag {
    font: 700 0.68rem 'Open Sans', sans-serif;
    letter-spacing: 0.08em;
    color: var(--white);
    background: var(--green);
    padding: 0.15rem 0.45rem;
    flex: 0 0 auto;
  }
  .import-route {
    font: 700 0.95rem 'Open Sans', sans-serif;
    color: var(--green);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Editable review-card fields — every value is correctable before adding. */
  .import-fields {
    margin-top: 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .import-fl {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
    flex: 1;
    min-width: 0;
  }
  .import-fl > span {
    font: 700 0.66rem 'Open Sans', sans-serif;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--green);
    opacity: 0.65;
  }
  .import-fin {
    width: 100%;
    padding: 0.45rem 0.55rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font: 400 0.9rem 'Open Sans', sans-serif;
    outline: none;
  }
  .import-fin:focus { border-color: var(--pink); }
  .import-field-row {
    display: flex;
    gap: 0.5rem;
  }
  .import-leg {
    margin-top: 0.2rem;
    padding-top: 0.55rem;
    border-top: 1px dashed var(--green-soft);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .import-leg-label {
    font: 700 0.68rem 'Open Sans', sans-serif;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--pink);
  }
  .import-cost {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--green-soft);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .import-cost-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font: 700 0.8rem 'Open Sans', sans-serif;
    color: var(--green);
    cursor: pointer;
  }
  .import-cost-head input {
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--pink);
    flex: 0 0 auto;
  }

  /* ----- Travelers roster ("who's on this trip") ----- */
  /* 1.25rem horizontal padding = the trip hero's gutter, so the roster aligns
     with the trip content instead of touching the screen edges. Minimal bottom
     margin so the tabs sit close beneath it (Megan: gap was too big). */
  .trip-travelers { margin: 0.1rem 0 0; padding: 0 1.25rem; }
  .trip-travelers-row,
  .trip-travelers-empty {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.45rem 0;
    color: var(--green);
    font: 400 0.9rem 'Open Sans', sans-serif;
    text-align: left;
  }
  .trip-travelers-row .ui-icon,
  .trip-travelers-empty .ui-icon { color: var(--pink); width: 1.1em; height: 1.1em; flex: 0 0 auto; }
  /* Empty state reads as a clear tappable action (underlined, not muted). */
  .trip-travelers-empty { color: var(--green); }
  .trip-travelers-empty span { text-decoration: underline; }
  .trip-travelers-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; flex: 1; min-width: 0; }
  .traveler-chip {
    background: var(--green-soft);
    color: var(--green);
    font: 600 0.78rem 'Open Sans', sans-serif;
    padding: 0.2rem 0.6rem;
    border-radius: 4px;
  }
  .trip-travelers-edit { font: 600 0.8rem 'Open Sans', sans-serif; color: var(--pink); flex: 0 0 auto; }
  .travelers-list { margin: 0.5rem 0; display: flex; flex-direction: column; gap: 0.4rem; }
  .traveler-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border: var(--border);
    padding: 0.5rem 0.7rem;
    color: var(--green);
    font: 400 0.95rem 'Open Sans', sans-serif;
  }
  .traveler-name { flex: 1; min-width: 0; }
  .traveler-status { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 0.25rem; }
  .traveler-status.linked { color: var(--green); opacity: 0.65; font: 600 0.72rem 'Open Sans', sans-serif; letter-spacing: 0.02em; }
  .traveler-status.linked .ui-icon { width: 0.95em; height: 0.95em; }
  .traveler-status.add {
    background: none;
    border: none;
    color: var(--pink);
    cursor: pointer;
    padding: 0;
    font: 600 0.78rem 'Open Sans', sans-serif;
  }
  .traveler-remove {
    background: none;
    border: none;
    color: var(--pink);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
  }
  .travelers-empty-note { color: var(--muted); font-size: 0.9rem; padding: 0.3rem 0; }
  .traveler-add-row { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
  .traveler-add-row input {
    flex: 1;
    padding: 0.55rem 0.7rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font: 400 0.95rem 'Open Sans', sans-serif;
    outline: none;
  }
  .traveler-add-row input:focus { border-color: var(--pink); }
  .traveler-add-row .btn-secondary { flex: 0 0 auto; width: auto; padding: 0.55rem 1.1rem; }

  .modal-actions button {
    flex: 1;
  }

  /* Stacked variant: primary action on top, secondary below.
     Used for friendly invitation modals (FB group, Year View hint, etc.) where
     we want the primary action to stand out and not be a "small button next to Cancel." */
  .modal-actions-stacked {
    flex-direction: column;
    gap: 0.55rem;
  }
  .modal-actions-stacked .btn-primary,
  .modal-actions-stacked .btn-secondary,
  .modal-actions-stacked button,
  .modal-actions-stacked a {
    flex: none;
    width: 100%;
    text-align: center;
    text-decoration: none;
  }

  /* Narrow modal: smaller width, more focused. For lightweight prompts (FB group
     invite, year-view hint promo) where there are no form fields, just a message. */
  .modal-narrow {
    max-width: 420px;
    text-align: center;
  }
  .modal-narrow .modal-sub {
    text-align: center;
    margin-left: auto;
    margin-right: auto;
    max-width: 360px;
  }
  .fb-modal-emoji {
    font-size: 2.6rem;
    line-height: 1;
    margin: 0.4rem 0 0.5rem;
  }

  /* ============ TRIP DETAIL VIEW ============ */
  .trip-hero {
    padding: 2rem 1.25rem 1.5rem;
    border-bottom: var(--border);
    position: relative;
  }
  .trip-hero-meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.6rem;
  }
  .trip-hero-meta-row .trip-hero-meta {
    margin-bottom: 0;
  }
  /* Icon-only square, identical to .trip-hero-camera-btn, so the camera and
     edit buttons match (Megan: not 3 different-size boxes). Pencil icon. */
  .trip-edit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem;
    color: var(--green);
    border: var(--border);
    background: var(--white);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  .trip-edit-btn svg { width: 14px; height: 14px; display: block; }
  /* :active is the brief "finger is down" state on touch — gives the green
     flash feedback then returns to white the instant the tap ends. iOS
     :hover is sticky (persists after tap until the user taps elsewhere),
     so we scope :hover to devices that actually have a pointer. */
  .trip-edit-btn:active {
    background: var(--green);
    color: var(--white);
    outline: none;
  }
  @media (hover: hover) {
    .trip-edit-btn:hover {
      background: var(--green);
      color: var(--white);
      outline: none;
    }
  }
  /* Icon-only camera button in the trip hero — opens the iOS photo picker so
     the user can set a background image for this trip. The same photo paints
     the home-screen widget AND the in-app trip hero, so the picker feels
     rewarding immediately. Padding matches .trip-edit-btn so the two
     buttons stand the same height in the action row; only the width is
     tighter because the icon is square. */
  .trip-hero-camera-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  .trip-hero-camera-btn svg {
    width: 14px;
    height: 14px;
    display: block;
  }
  .trip-hero-camera-btn:active {
    background: var(--green);
    color: var(--white);
    outline: none;
  }
  @media (hover: hover) {
    .trip-hero-camera-btn:hover {
      background: var(--green);
      color: var(--white);
      outline: none;
    }
  }
  /* When a photo is set, the photo IS the visible signal — it's right
     there behind the hero, and the "Remove widget photo" link sits below
     the stats. So the camera button stays in its neutral white/green
     outline state instead of locking to a filled fill, keeping the hero
     action row visually calm. Kept as a hook for any future tweaks. */
  .trip-hero-camera-btn.has-photo { }

  /* When a trip has a widget photo set, paint it as a soft background behind
     the existing hero content. The translucent white gradient overlay keeps
     the destination title, dates, and stat cards legible regardless of what
     the user picks. The chosen photo is stored in IndexedDB keyed by tripId
     and applied via inline `background-image: url(data:...)` on .trip-hero. */
  .trip-hero.has-photo {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    isolation: isolate;
  }
  .trip-hero.has-photo::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
      rgba(255, 255, 255, 0.78) 0%,
      rgba(255, 255, 255, 0.66) 45%,
      rgba(255, 255, 255, 0.92) 100%);
    pointer-events: none;
    z-index: 0;
  }
  .trip-hero.has-photo > * {
    position: relative;
    z-index: 1;
  }
  /* When a photo is behind the hero, swap the title + dates to the site's
     body charcoal (#333). Keeps brand green/muted gray for the no-photo
     state but boosts contrast wherever a photo lands so legibility doesn't
     depend on whatever colors the user picked. */
  .trip-hero.has-photo h1,
  .trip-hero.has-photo .trip-hero-dates {
    color: #333;
  }

  /* Subtle text-link to remove a trip's widget photo. Sits below the hero
     stats and only shows when a photo is set for this trip. */
  .trip-widget-photo-remove {
    margin-top: 0.6rem;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    padding: 0.2rem 0;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: color 0.15s;
  }
  .trip-widget-photo-remove:hover, .trip-widget-photo-remove:focus-visible {
    color: var(--pink);
    outline: none;
  }

  .trip-hero-meta {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--pink);
    margin-bottom: 0.6rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
  }
  .trip-hero-meta::before {
    content: '';
    width: 20px; height: 1.5px;
    background: var(--pink);
  }
  .trip-hero h1 {
    font-size: clamp(2rem, 7.5vw, 2.75rem);
    line-height: 1.05;
    letter-spacing: -0.015em;
    margin-bottom: 0.75rem;
  }
  .trip-hero-dates {
    font-size: 0.95rem;
    color: var(--muted);
    font-weight: 500;
    letter-spacing: 0.02em;
    margin-bottom: 1.25rem;
  }
  .trip-hero-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
  }
  .trip-stat {
    padding: 0.85rem 1rem;
    border: var(--border);
    background: var(--green-soft);
  }
  .trip-stat.accent { background: var(--pink-soft); border-color: var(--pink); }
  .trip-stat-val {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.6rem;
    color: var(--green);
    line-height: 1;
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
  }
  .trip-stat.accent .trip-stat-val { color: var(--pink-deep); }
  .trip-stat-val .unit {
    font-size: 0.72rem;
    font-family: 'Open Sans', sans-serif;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.14em;
  }
  .trip-stat-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    margin-top: 0.35rem;
  }

  /* Tab bar */
  .tabs {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    padding: 0 0.5rem;
    border-bottom: var(--border);
    background: var(--white);
    position: sticky;
    /* Build 33: top value updated to match the new tightened topbar height
       (~1.6rem + safe-area). Previously this was 3.5rem which left a visible
       gap between topbar bottom and tabs top — content scrolled through it. */
    top: calc(1.6rem + env(safe-area-inset-top));
    z-index: 40;
  }
  .tab {
    flex: 1 1 0;
    min-width: 0;
    padding: 1rem 0.25rem;
    font-size: 0.64rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--muted);
    position: relative;
    text-align: center;
    transition: color 0.15s;
    background: transparent;
    white-space: nowrap;
  }
  @media (min-width: 420px) {
    .tab { font-size: 0.7rem; letter-spacing: 0.14em; }
  }
  .tab.active {
    color: var(--green);
  }
  .tab.active::after {
    content: '';
    position: absolute;
    bottom: -1.5px;
    left: 50%;
    transform: translateX(-50%);
    width: 60%;
    height: 3px;
    background: var(--pink);
  }

  /* Pin a default tab — small button in the trip header that opens a popup */
  .trip-hero-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .pin-default-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.7rem 0.4rem 0.6rem;
    border: 1px solid var(--green);
    background: var(--white);
    color: var(--green);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    line-height: 1;
    -webkit-tap-highlight-color: transparent;
  }
  /* Green flash during press, back to white when released — same pattern
     as .trip-edit-btn so the whole hero action row behaves identically.
     :hover scoped to pointer devices so iOS doesn't stick after tap. */
  .pin-default-btn:active {
    background: var(--green);
    color: var(--white);
    outline: none;
  }
  .pin-default-btn:active .pin-icon::before,
  .pin-default-btn:active .pin-icon::after {
    background: var(--white);
  }
  @media (hover: hover) {
    .pin-default-btn:hover {
      background: var(--green);
      color: var(--white);
      outline: none;
    }
    .pin-default-btn:hover .pin-icon::before,
    .pin-default-btn:hover .pin-icon::after {
      background: var(--white);
    }
  }
  /* When something is pinned, the LABEL text already says which tab is
     set ("ITINERARY"). The button stays in its neutral white/green outline
     state to keep the hero visually calm — no persistent pink fill.
     Kept as an empty rule so any future state tweaks have a hook. */
  .pin-default-btn.has-pin { }

  /* The pin shape, drawn as a small head + stem icon */
  .pin-icon {
    position: relative;
    display: inline-block;
    width: 0.85rem;
    height: 0.85rem;
    flex: 0 0 auto;
  }
  .pin-icon::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: var(--green);
    transition: background 0.15s;
  }
  .pin-icon::after {
    content: '';
    position: absolute;
    top: 0.45rem;
    left: 50%;
    transform: translateX(-50%);
    width: 1.5px;
    height: 0.45rem;
    background: var(--green);
    transition: background 0.15s;
  }

  /* Popup with tab options */
  .pin-default-popup {
    position: absolute;
    z-index: 100;
    display: none;
    background: var(--white);
    border: var(--border);
    box-shadow: 6px 6px 0 var(--green);
    padding: 0.4rem 0;
    min-width: 180px;
  }
  .pin-default-popup.shown { display: block; }
  .pin-default-popup-title {
    padding: 0.45rem 0.85rem 0.55rem;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--pink);
    border-bottom: 1px solid var(--green-soft);
    margin-bottom: 0.25rem;
  }
  .pin-default-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.6rem 0.85rem;
    background: none;
    border: none;
    text-align: left;
    font-size: 0.92rem;
    color: var(--text);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
  }
  .pin-default-option:hover, .pin-default-option:focus-visible {
    background: var(--green-soft);
    outline: none;
  }
  .pin-default-option.active {
    color: var(--pink-deep);
    font-weight: 600;
  }
  .pin-default-option-check {
    visibility: hidden;
    color: var(--pink);
    font-weight: 700;
  }
  .pin-default-option.active .pin-default-option-check {
    visibility: visible;
  }

  /* Pin tooltip — small floating message after pin change */
  .pin-toast {
    position: fixed;
    bottom: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    background: var(--green);
    color: var(--white);
    padding: 0.7rem 1.1rem;
    font-size: 0.82rem;
    font-weight: 600;
    z-index: 200;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
    max-width: 90vw;
    text-align: center;
  }
  .pin-toast.shown {
    opacity: 1;
  }
  .tab.locked {
    opacity: 0.55;
    cursor: not-allowed;
  }

  .tab-panel {
    display: none;
    padding: 1.75rem 1.25rem 3rem;
  }
  .tab-panel.active { display: block; animation: viewFade 0.15s ease; }
  /* Build 35: bucket list panels have their own internal spacing (.bl-stat-wrap
     and .bl-controls have their own padding), so the .tab-panel's default
     1.75rem top padding stacks with that and creates too big a gap between
     the tabs and the "0 of 195" progress tracker. Tighten just bucketlist. */
  #view-bucketlist .tab-panel { padding-top: 0; }
  /* Build 25: extra bottom padding on the Notes tab so the input field can be
     scrolled above the keyboard on mobile (same reason as the modal padding-
     bottom added in Build 21). The Notes input sits at the bottom of the page;
     without scroll room beneath it, the keyboard will cover it. */
  @media (max-width: 599px) {
    .tab-panel[data-panel="notes"] { padding-bottom: 280px; }
  }

  /* ============ TIMELINE / CHECKLIST ============ */
  .panel-intro {
    margin-bottom: 1.75rem;
  }
  .panel-intro h2 {
    font-size: 1.35rem;
    line-height: 1.15;
    margin-bottom: 0.5rem;
  }
  .panel-intro p {
    color: var(--muted);
    font-size: 0.9rem;
  }

  .booking-card {
    border: var(--border);
    padding: 1.25rem 1.2rem;
    background: var(--white);
    box-shadow: 0 12px 44px rgba(0,71,69,0.22);
    margin-bottom: 2rem;
  }
  .booking-card .tag {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--pink);
    margin-bottom: 0.65rem;
  }
  .booking-card .label {
    font-size: 0.75rem;
    color: var(--muted);
    margin-bottom: 0.25rem;
  }
  .booking-card .date {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.75rem;
    color: var(--green);
    line-height: 1.1;
    margin-bottom: 1rem;
  }
  .booking-card .note {
    font-size: 0.85rem;
    color: var(--muted);
    padding-top: 1rem;
    border-top: 1px dashed var(--green);
    line-height: 1.55;
  }
  .booking-card .note em { color: var(--pink); font-style: normal; font-weight: 700; }

  .timeline {
    display: flex;
    flex-direction: column;
  }
  .timeline-item {
    position: relative;
    padding: 1.15rem 0 1.15rem 2.5rem;
    border-bottom: 1px solid var(--green-soft);
    display: flex;
    gap: 1rem;
    align-items: flex-start;
  }
  .timeline-item::before {
    content: '';
    position: absolute;
    left: 0.65rem; top: 1.9rem; bottom: -1px;
    width: 1.5px;
    background: var(--green-soft);
  }
  .timeline-item:last-child::before { display: none; }
  .timeline-check {
    position: absolute;
    left: 0;
    top: 1.25rem;
    width: 1.4rem;
    height: 1.4rem;
    border: var(--border);
    background: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: transparent;
    transition: all 0.18s;
    flex-shrink: 0;
  }
  /* No pink hover outline — just the basic border at rest, and the filled
     green "done" state below when checked. Keeps the timeline visually
     calm regardless of where the user's tap lands. */
  .timeline-item.done .timeline-check {
    background: var(--green);
    border-color: var(--green);
    color: var(--white);
  }
  .timeline-item.milestone-urgent:not(.done) .timeline-check {
    border-color: var(--pink);
    animation: pulse 1.8s ease-in-out infinite;
  }
  @keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(216, 17, 89, 0.5); } 50% { box-shadow: 0 0 0 6px rgba(216, 17, 89, 0); } }
  /* LATE_BUT_ACTIONABLE: ideal window has passed but trip hasn't started.
     Amber treatment — caution, not failure. The milestone is still relevant
     and the user gets late-booking advice in place of the ideal-window text. */
  .timeline-item.milestone-late:not(.done) .timeline-check {
    border-color: var(--amber);
    background: var(--amber-soft);
  }
  .timeline-item.milestone-late:not(.done) .timeline-date { color: var(--amber); }
  .timeline-item.milestone-late:not(.done) .timeline-days { color: var(--amber); }
  /* Late-state clock icon next to the milestone title. We always size the SVG
     (regardless of done state) so it can't blow up to its viewBox dimensions
     if the user checks the box without re-rendering. When the item IS done,
     the strikethrough + check already communicates state — hide the icon. */
  .timeline-late-icon {
    display: inline-flex;
    color: var(--amber);
    margin-right: 0.4rem;
    vertical-align: -2px;
  }
  .timeline-late-icon svg {
    width: 0.95em;
    height: 0.95em;
  }
  .timeline-item.done .timeline-late-icon { display: none; }
  /* Legacy state — kept for any code paths that still set this class. */
  .timeline-item.milestone-past:not(.done) .timeline-check { opacity: 0.4; }

  /* Trip-in-progress or trip-complete: timeline replaced with a friendly
     status card instead of the 12 milestones (which are no longer actionable). */
  .timeline-status-message {
    border: var(--border);
    box-shadow: 6px 6px 0 var(--green);
    background: var(--white);
    padding: 1.75rem 1.5rem;
    text-align: center;
  }
  .timeline-status-message h3 {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.4rem;
    color: var(--green);
    margin-bottom: 0.5rem;
  }
  .timeline-status-message h3 em { color: var(--pink); }
  .timeline-status-message p {
    color: var(--muted);
    font-size: 0.95rem;
    max-width: 32em;
    margin: 0 auto;
  }

  .timeline-body { flex: 1; min-width: 0; }
  .timeline-date {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--muted);
    margin-bottom: 0.25rem;
  }
  .timeline-item.milestone-urgent .timeline-date { color: var(--pink); }
  .timeline-item.done .timeline-date { text-decoration: line-through; opacity: 0.6; }
  .timeline-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.05rem;
    color: var(--green);
    margin-bottom: 0.3rem;
    line-height: 1.2;
  }
  .timeline-item.done .timeline-title { text-decoration: line-through; opacity: 0.55; }
  .timeline-desc {
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.55;
  }
  .timeline-item.done .timeline-desc { opacity: 0.55; }
  .timeline-days {
    font-size: 0.68rem;
    font-weight: 700;
    color: var(--pink);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    margin-top: 0.4rem;
  }
  .timeline-item.milestone-past:not(.done) .timeline-days { color: var(--muted); }
  .timeline-item.done .timeline-days { display: none; }

  /* Per-milestone action row: shortcut CTA on the left, "Learn more" on the right.
     Keeps the checklist scannable — full advice lives in the expandable panel below. */
  .timeline-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.5rem;
    flex-wrap: wrap;
  }
  .timeline-cta {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--pink-deep);
    text-decoration: none;
    border-bottom: 1.5px solid var(--pink);
    padding-bottom: 1px;
    line-height: 1;
    cursor: pointer;
    background: none;
    border-top: none;
    border-left: none;
    border-right: none;
    padding-left: 0;
    padding-right: 0;
    transition: color 0.12s, border-color 0.12s;
  }
  .timeline-cta:hover { color: var(--pink); border-color: var(--pink-deep); }
  .timeline-item.done .timeline-cta { opacity: 0.55; }
  /* Secondary link variant (e.g. external resource link beside a primary CTA).
     Muted green tone so it's clearly secondary to the pink CTA. */
  .timeline-cta-secondary {
    color: var(--green);
    border-bottom-color: var(--green);
  }
  .timeline-cta-secondary:hover { color: var(--green-deep); border-color: var(--green-deep); }
  .timeline-learn-more {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    cursor: pointer;
    background: none;
    padding: 0;
    margin-left: auto;
  }
  .timeline-learn-more:hover { color: var(--green); }
  .timeline-learn-more::after { content: ' ▾'; display: inline-block; transition: transform 0.15s; }
  .timeline-learn-more.expanded::after { transform: rotate(180deg); }
  .timeline-details {
    margin-top: 0.6rem;
    padding: 0.65rem 0.85rem;
    background: var(--green-soft);
    border-left: 2.5px solid var(--green);
    font-size: 0.85rem;
    color: var(--ink);
    line-height: 1.55;
    display: none;
  }
  .timeline-details.shown { display: block; }
  .timeline-item.milestone-late:not(.done) .timeline-details {
    background: var(--amber-soft);
    border-left-color: var(--amber);
  }

  /* Coming soon panel */
  .coming-soon {
    border: var(--border);
    padding: 2rem 1.5rem;
    text-align: center;
    box-shadow: 6px 6px 0 var(--green);
    background: var(--green-soft);
  }
  .coming-soon h3 {
    font-size: 1.3rem;
    margin-bottom: 0.5rem;
  }
  .coming-soon p {
    color: var(--muted);
    font-size: 0.9rem;
    max-width: 28em;
    margin: 0 auto;
  }

  /* ============ CONFIRM DIALOG ============ */
  .confirm .modal { max-width: 420px; }
  .confirm h2 { font-size: 1.25rem; }
  .confirm .confirm-body { font-size: 0.9rem; color: var(--muted); margin-bottom: 1.25rem; }

  /* Context menu for trip card */
  .ctx-menu {
    position: absolute;
    z-index: 100;
    background: var(--white);
    border: var(--border);
    display: none;
    min-width: 160px;
  }
  .ctx-menu.shown { display: block; animation: ctxFade 0.15s ease; }
  /* Dim the page behind any open context menu so the menu doesn't visually
     compete with the card data underneath it (the menu still positions
     relative to its trigger button — the backdrop just makes it clearly
     "in front of" the card content). Click the backdrop to dismiss. */
  .ctx-menu-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 71, 69, 0.18);
    z-index: 99;
    display: none;
  }
  .ctx-menu-backdrop.shown { display: block; animation: backdropFade 0.15s ease; }
  @keyframes ctxFade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
  .ctx-menu button {
    display: block;
    width: 100%;
    padding: 0.7rem 0.95rem;
    text-align: left;
    font-size: 0.82rem;
    color: var(--green);
    border-bottom: 1px solid var(--green-soft);
  }
  .ctx-menu button:last-child { border-bottom: none; }
  .ctx-menu button:hover { background: var(--green-soft); }
  .ctx-menu button.danger { color: var(--danger); }
  .ctx-menu button.danger:hover { background: var(--danger-soft); }

  /* ============ TOOLS SECTION ============ */
  .tools-section {
    padding: 0.5rem 1.25rem 1.25rem;
  }
  .tools-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.85rem;
  }
  @media (min-width: 480px) {
    .tools-grid { grid-template-columns: 1fr 1fr; }
  }
  /* On the wider iPad/desktop column, the three tool cards sit in one row. */
  @media (min-width: 760px) {
    .tools-grid { grid-template-columns: 1fr 1fr 1fr; }
  }
  .tool-card {
    border: var(--border);
    padding: 1rem 1.1rem 1.1rem;
    background: var(--white);
    box-shadow: 5px 5px 0 var(--green);
    text-align: left;
    display: block;
    transition: transform 0.15s, box-shadow 0.15s;
    position: relative;
    width: 100%;
  }
  .tool-card:hover, .tool-card:focus-visible {
    transform: translate(-2px, -2px);
    box-shadow: 7px 7px 0 var(--pink);
    outline: none;
  }
  .tool-card.locked {
    box-shadow: 5px 5px 0 var(--muted);
    opacity: 0.75;
    cursor: not-allowed;
  }
  .tool-card.locked:hover { transform: none; box-shadow: 5px 5px 0 var(--muted); }
  .tool-card-tag {
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--pink);
    margin-bottom: 0.35rem;
  }
  .tool-card.locked .tool-card-tag { color: var(--muted); }
  .tool-card-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--green);
    line-height: 1.15;
    margin-bottom: 0.35rem;
  }
  .tool-card-desc {
    font-size: 0.8rem;
    color: var(--muted);
    line-height: 1.45;
  }

  /* ============ FOOTER SOCIAL ICONS ============
     Three small green icons centered in the footer, sitting between the copyright
     line and the legal/utility links row. Subtle, on-brand, doesn't shout for attention. */
  .footer-socials {
    display: flex;
    justify-content: center;
    gap: 1.4rem;
    margin: 0.75rem 0 0.85rem;
  }
  .footer-socials a {
    color: var(--green);
    line-height: 0;
    /* 44×44 minimum touch target (iOS HIG). Visible icon size unchanged;
       padding just expands the tappable hit area. */
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
    transition: color 0.15s, transform 0.15s;
  }
  .footer-socials a:hover,
  .footer-socials a:focus-visible {
    color: var(--pink);
    transform: translateY(-1px);
    outline: none;
  }
  .footer-socials svg {
    display: block;
  }

  /* CTA link inside an empty state. Used in Wishlist empty state to point users
     to the Travel Keeper List as a source of inspiration when they have no ideas yet. */
  .empty-cta-link {
    margin-top: 1.4rem;
    padding-top: 1.2rem;
    border-top: 1px dashed var(--green-soft);
  }
  .empty-cta-link a {
    display: inline-block;
    color: var(--pink-deep);
    font-size: 0.88rem;
    font-weight: 600;
    text-decoration: none;
    line-height: 1.4;
  }
  .empty-cta-link a:hover { color: var(--pink); text-decoration: underline; }
  .empty-cta-sub {
    font-size: 0.74rem;
    color: var(--muted);
    margin-top: 0.3rem;
    /* Italics removed for accessibility — italic small text is hard to read,
       especially for dyslexic users. Italics now reserved for headline accents
       only (the brand <em> highlight). */
  }

  /* Subtle CTA inside the Stay entry form. Surfaces the Travel Keeper List right at
     the decision moment when the user is filling in lodging details. Pink-soft block
     with brand styling, doesn't overshadow the form fields. */
  .stay-list-cta {
    margin: 0 0 1rem;
    padding: 0.7rem 0.85rem;
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
  }
  .stay-list-cta a {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    color: var(--green);
    text-decoration: none;
    font-size: 0.83rem;
    line-height: 1.45;
  }
  .stay-list-cta a:hover .stay-list-cta-text { color: var(--pink-deep); }
  .stay-list-cta-icon {
    font-size: 1.05rem;
    flex-shrink: 0;
  }
  .stay-list-cta-text strong {
    color: var(--pink-deep);
    font-weight: 700;
  }

  /* ============ PRIVACY INDICATOR ============ */
  .privacy-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.65rem;
    background: var(--green-soft);
    border: 1px solid var(--green);
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--green);
    letter-spacing: 0.08em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
  }
  .privacy-chip:hover { background: var(--green); color: var(--white); }
  .privacy-chip .lock { font-size: 0.72rem; }

  /* First-time privacy banner */
  .privacy-banner {
    margin: 0 1.25rem 1rem;
    padding: 1rem 1.1rem 1rem 1.1rem;
    border: var(--border);
    border-left: 4px solid var(--pink);
    background: var(--pink-soft);
    position: relative;
    display: none;
  }
  .privacy-banner.shown { display: block; animation: slideIn 0.4s ease; }
  .privacy-banner-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
    margin-bottom: 0.35rem;
  }
  .privacy-banner-body {
    font-size: 0.85rem;
    color: var(--green-deep);
    line-height: 1.55;
  }
  .privacy-banner-body em { color: var(--pink-deep); font-weight: 600; font-style: normal; }
  .privacy-banner-body .link-inline {
    color: var(--pink-deep);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    cursor: pointer;
  }
  .privacy-banner-body .link-inline:hover { color: var(--pink); }
  .privacy-banner .close {
    position: absolute;
    top: 0.45rem; right: 0.55rem;
    font-size: 1.2rem;
    color: var(--muted);
    line-height: 1;
    padding: 0.25rem 0.5rem;
  }
  .privacy-banner .close:hover { color: var(--pink); }

  /* Full privacy explainer modal */
  .privacy-info .modal { max-width: 480px; }
  .privacy-info h2 { font-size: 1.4rem; }
  .privacy-info p { font-size: 0.9rem; color: var(--ink); margin-bottom: 0.85rem; line-height: 1.6; }
  .privacy-info p:last-of-type { margin-bottom: 1.25rem; }
  .privacy-info ul { margin: 0 0 1rem 1.25rem; font-size: 0.9rem; color: var(--ink); }
  .privacy-info ul li { margin-bottom: 0.4rem; line-height: 1.55; }

  /* ============ PASSPORT TOOL VIEW ============ */
  .passport-hero {
    padding: 1.25rem 1.25rem 1rem;
    border-bottom: var(--border);
  }
  .passport-hero h1 {
    font-size: clamp(1.75rem, 6.5vw, 2.4rem);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
  }
  .passport-hero p {
    color: var(--muted);
    font-size: 0.92rem;
    margin-bottom: 1.25rem;
  }
  .passport-hero-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
  }

  .passport-section {
    padding: 1.5rem 1.25rem 2rem;
  }

  /* Trip-check panel (in passport tool) */
  .tripcheck-card {
    border: var(--border);
    padding: 1.05rem 1.1rem;
    background: var(--white);
    box-shadow: 6px 6px 0 var(--green);
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
  }
  .tripcheck-card .tag {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--pink);
    margin-bottom: 0.55rem;
  }
  .tripcheck-card h3 {
    font-size: 1.15rem;
    margin-bottom: 0.5rem;
    line-height: 1.2;
  }
  .tripcheck-card .prompt {
    font-size: 0.88rem;
    color: var(--muted);
    margin-bottom: 0.85rem;
  }
  .tripcheck-card .tripcheck-select {
    width: 100%;
    padding: 0.7rem 0.8rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23d81159' stroke-width='2' fill='none'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    padding-right: 2rem;
  }
  .tripcheck-card .tripcheck-select:focus { border-color: var(--pink); }
  .tripcheck-summary {
    margin-top: 0.85rem;
    padding-top: 0.85rem;
    border-top: 1px dashed var(--green);
    font-size: 0.9rem;
    color: var(--ink);
    line-height: 1.55;
  }
  .tripcheck-summary strong { color: var(--pink-deep); font-weight: 700; }
  .tripcheck-summary.all-good { color: var(--green); }

  /* Family list */
  .family-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 1rem;
    gap: 1rem;
  }
  .family-header h2 { font-size: 1.25rem; }

  .family-empty {
    border: var(--border);
    padding: 1.75rem 1.4rem;
    text-align: center;
    box-shadow: 6px 6px 0 var(--green);
    margin-bottom: 1rem;
  }
  .family-empty h3 {
    font-size: 1.15rem;
    margin-bottom: 0.4rem;
  }
  .family-empty p {
    color: var(--muted);
    font-size: 0.88rem;
    margin-bottom: 1.1rem;
    max-width: 26em;
    margin-left: auto;
    margin-right: auto;
  }

  .family-list {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    margin-bottom: 1rem;
  }

  .person-card {
    border: var(--border);
    padding: 0.85rem 1rem 0.95rem;
    background: var(--white);
    box-shadow: 5px 5px 0 var(--green);
    position: relative;
  }
  .person-card.status-expired { box-shadow: 5px 5px 0 var(--pink); border-color: var(--pink); }
  .person-card.status-warn { box-shadow: 5px 5px 0 var(--pink); }

  /* Drag handle for reordering family members */
  .person-card-handle {
    position: absolute;
    top: 0.5rem;
    left: 0.45rem;
    color: var(--muted);
    cursor: grab;
    font-size: 1.05rem;
    padding: 0.15rem 0.3rem;
    user-select: none;
    line-height: 1;
    touch-action: none;
  }
  .person-card-handle:hover { color: var(--pink); }
  .person-card-handle:active { cursor: grabbing; }

  /* Sortable JS placeholder while dragging family cards */
  .person-card.sortable-ghost {
    opacity: 0.4;
    background: var(--pink-soft);
  }
  .person-card.sortable-chosen {
    background: var(--white);
  }

  .person-row {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    padding-left: 1.4rem; /* room for drag handle on the left */
  }
  .person-badge {
    width: 42px; height: 42px;
    flex-shrink: 0;
    border: var(--border);
    background: var(--green-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
  }
  .person-card.status-expired .person-badge,
  .person-card.status-warn .person-badge { background: var(--pink-soft); color: var(--pink-deep); border-color: var(--pink); }
  .person-info { flex: 1; min-width: 0; padding-right: 2rem; }
  .person-name {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--green);
    line-height: 1.15;
    margin-bottom: 0.2rem;
  }
  .person-meta {
    font-size: 0.75rem;
    color: var(--muted);
    letter-spacing: 0.04em;
  }
  .person-menu {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    padding: 0.35rem 0.55rem;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1;
    background: none;
    border: none;
    cursor: pointer;
  }
  .person-menu:hover { color: var(--pink); }

  .person-status {
    margin-top: 0.65rem;
    margin-left: 1.4rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--green);
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
  }
  .status-line {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
  }
  .status-line .icon {
    flex-shrink: 0;
    width: 18px;
    font-weight: 700;
    text-align: center;
  }
  /* When the .icon span contains an inline SVG (Lucide replacement), size it
     to match adjacent text. The SVG inherits color via currentColor from the
     status-color variants (.ok, .warn, .info) above. */
  .status-line .icon svg {
    width: 14px;
    height: 14px;
    display: inline-block;
    vertical-align: middle;
    stroke-width: 1.75;
  }
  .status-line.ok { color: var(--green); }
  .status-line.ok .icon { color: var(--green); }
  .status-line.warn { color: var(--pink-deep); }
  .status-line.warn .icon { color: var(--pink); }
  .status-line.info { color: var(--muted); }
  .status-line.info .icon { color: var(--muted); }
  .renewal-link {
    color: var(--pink-deep);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 2px;
    white-space: nowrap;
    margin-left: 0.2rem;
  }
  .renewal-link:hover { color: var(--pink); }

  /* US guidance callout */
  .us-guidance {
    margin-top: 1rem;
    padding: 0.9rem 1.05rem;
    border: 1.5px dashed var(--green);
    background: var(--green-soft);
    font-size: 0.82rem;
    color: var(--ink);
    line-height: 1.55;
  }
  .us-guidance strong { color: var(--green); }
  .us-guidance em { color: var(--pink-deep); font-style: normal; font-weight: 700; }

  /* ============ LOYALTY PROGRAMS ============ */
  /* Section appears inline within each person card, beneath passport status */
  .loyalty-section {
    margin-top: 0.7rem;
    margin-left: 1.4rem; /* align with person info, past the drag handle */
    padding-top: 0.55rem;
    border-top: 1px dashed var(--green-soft);
  }
  .loyalty-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    padding: 0.5rem 0;
    cursor: pointer;
    color: var(--green);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    text-align: left;
    transition: color 0.15s;
  }
  .loyalty-toggle:hover, .loyalty-toggle:focus-visible {
    color: var(--pink);
    outline: none;
  }
  /* Bigger chevron, on the right side as the primary affordance */
  .loyalty-toggle .chev {
    font-size: 1.1rem;
    transition: transform 0.2s;
    display: inline-block;
    color: var(--pink);
    line-height: 1;
    margin-left: 0.5rem;
  }
  .loyalty-toggle.expanded .chev {
    transform: rotate(90deg);
  }
  .loyalty-toggle .label {
    flex: 1;
  }
  .loyalty-toggle .count {
    color: var(--muted);
    font-weight: 600;
    letter-spacing: 0.1em;
    margin-right: 0.4rem;
  }
  .loyalty-list {
    display: none;
    margin-top: 0.5rem;
  }
  .loyalty-toggle.expanded + .loyalty-list { display: block; }

  .loyalty-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto auto;
    gap: 0.5rem 0.7rem;
    align-items: center;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--green-soft);
  }
  /* Variant: program has no member number (e.g. flexible currencies like Chase UR).
     Drop the number/lock columns — just drag, program, menu. */
  .loyalty-row.no-number {
    grid-template-columns: auto 1fr auto;
  }
  .loyalty-row:last-child { border-bottom: none; }

  /* Drag handle for reordering loyalty programs within a person */
  .loyalty-row-drag {
    color: var(--muted);
    cursor: grab;
    font-size: 1.05rem;
    padding: 0.1rem 0.25rem;
    user-select: none;
    line-height: 1;
    touch-action: none; /* lets SortableJS take the touch event before scroll kicks in */
  }
  .loyalty-row-drag:hover { color: var(--pink); }
  .loyalty-row-drag:active { cursor: grabbing; }

  .loyalty-row-program {
    font-size: 0.92rem;
    color: var(--text);
    font-weight: 600;
    line-height: 1.25;
    min-width: 0;
    word-break: break-word;
  }
  /* Balance line — visual prominence below the program name */
  .loyalty-row-balance {
    grid-column: 2 / -1;
    font-size: 0.95rem;
    color: var(--green);
    font-weight: 700;
    line-height: 1.25;
    margin-top: 0.1rem;
  }
  .loyalty-row-balance .updated {
    font-size: 0.74rem;
    font-weight: 500;
    color: var(--muted);
    letter-spacing: 0;
    margin-left: 0.4rem;
  }
  .loyalty-row-tier {
    grid-column: 2 / -1;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--pink-deep);
    font-weight: 700;
    margin-top: 0.15rem;
  }
  .loyalty-row-number {
    font-family: 'Open Sans', sans-serif;
    font-size: 0.88rem;
    color: var(--green);
    letter-spacing: 0.04em;
    text-align: right;
    white-space: nowrap;
  }
  .loyalty-row-number.masked {
    letter-spacing: 0.08em;
  }
  .loyalty-row-notes {
    grid-column: 1 / -1;
    font-size: 0.78rem;
    color: var(--muted);
    line-height: 1.5;
    margin-top: 0.15rem;
  }

  /* Sortable JS placeholder while dragging */
  .loyalty-row.sortable-ghost {
    opacity: 0.4;
    background: var(--pink-soft);
  }
  .loyalty-row.sortable-chosen {
    background: var(--white);
  }

  /* Branded lock-icon button to reveal/mask the number */
  .loyalty-lock-btn {
    background: none;
    border: none;
    padding: 0.35rem;
    cursor: pointer;
    line-height: 0;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.12s;
  }
  .loyalty-lock-btn:hover { transform: scale(1.08); }
  .loyalty-lock-btn:active { transform: scale(0.92); }

  /* Lock icon SVG: a small padlock that picks up brand colors via currentColor */
  .lock-icon {
    width: 1.05rem;
    height: 1.05rem;
    color: var(--green);
    transition: color 0.15s;
    display: inline-block;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23004745' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='11' width='14' height='10' rx='1.5'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
  }
  .loyalty-lock-btn.unlocked .lock-icon {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a00d42' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='11' width='14' height='10' rx='1.5'/><path d='M8 11V7a4 4 0 0 1 7.5-1.7'/></svg>");
  }

  .loyalty-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.85rem;
    padding: 0.5rem 0.9rem;
    background: var(--white);
    border: 1px dashed var(--green);
    color: var(--green);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
  }
  .loyalty-add-btn:hover, .loyalty-add-btn:focus-visible {
    background: var(--green);
    color: var(--white);
    outline: none;
  }
  .loyalty-add-btn .plus { font-size: 1rem; line-height: 1; font-weight: 400; }

  .loyalty-empty {
    color: var(--muted);
    font-size: 0.82rem;
    font-style: italic;
    padding: 0.4rem 0;
  }

  .loyalty-row-menu {
    grid-row: 1;
    grid-column: -2 / -1; /* always last column on first row, regardless of variant */
    background: none;
    border: none;
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1;
    padding: 0.3rem 0.5rem;
    cursor: pointer;
  }
  .loyalty-row-menu:hover { color: var(--pink); }

  /* Loyalty modal */
  .loyalty-program-field {
    position: relative;
  }
  .loyalty-suggestions {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    background: var(--white);
    border: var(--border);
    border-top: none;
    max-height: 200px;
    overflow-y: auto;
    box-shadow: 0 4px 8px rgba(0,0,0,0.06);
  }
  .loyalty-suggestions.shown { display: block; }
  .loyalty-suggestion {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.6rem 0.85rem;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.92rem;
    color: var(--text);
    border-bottom: 1px solid var(--green-soft);
  }
  .loyalty-suggestion:last-child { border-bottom: none; }
  .loyalty-suggestion:hover, .loyalty-suggestion.highlighted {
    background: var(--green-soft);
    color: var(--green);
  }
  .loyalty-suggestion.custom-add {
    color: var(--pink-deep);
    font-style: italic;
  }
  .loyalty-suggestion.divider {
    pointer-events: none;
    color: var(--muted);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    background: var(--green-soft);
    cursor: default;
  }

  .loyalty-privacy-note {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.65rem 0.75rem;
    background: var(--green-soft);
    border-left: 2px solid var(--green);
    font-size: 0.78rem;
    color: var(--green);
    line-height: 1.5;
    margin-top: 0.5rem;
    margin-bottom: 0.5rem;
  }
  .loyalty-privacy-note .lock-icon {
    flex: 0 0 auto;
    width: 0.95rem;
    height: 0.95rem;
  }

  /* Form for add/edit family member */
  .form-field select {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23d81159' stroke-width='2' fill='none'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    padding-right: 2rem;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .form-field select:focus { border-color: var(--pink); }
  .form-field textarea {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    resize: vertical;
    min-height: 4rem;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .form-field textarea:focus { border-color: var(--pink); }

  /* Typeable date input */
  #person-expiry-input {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
    letter-spacing: 0.02em;
  }
  #person-expiry-input:focus {
    border-color: var(--pink);
  }
  #person-expiry-input.invalid {
    border-color: var(--pink);
    background: var(--pink-soft);
  }

  /* Typeable date combo (input + calendar button) */
  .date-combo {
    display: flex;
    gap: 0;
    width: 100%;
  }
  .date-combo input {
    flex: 1;
    min-width: 0;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    border-right: none;
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .date-combo input:focus {
    border-color: var(--pink);
  }
  .date-combo input.invalid {
    border-color: var(--pink);
    background: var(--pink-soft);
  }
  .date-combo-cal {
    padding: 0.65rem 0.85rem;
    border: var(--border);
    background: var(--green-soft);
    color: var(--green);
    font-size: 1.05rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    flex-shrink: 0;
  }
  .date-combo-cal:hover, .date-combo-cal:focus-visible {
    background: var(--green);
    color: var(--white);
    outline: none;
  }

  /* ============ PROGRESS BAR ============ */
  .progress-wrap {
    margin-bottom: 1.75rem;
  }
  .progress-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 0.5rem;
  }
  .progress-label {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--muted);
  }
  .progress-count {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
  }
  .progress-track {
    height: 10px;
    border: var(--border);
    background: var(--green-soft);
    position: relative;
    overflow: hidden;
  }
  .progress-fill {
    height: 100%;
    background: var(--pink);
    width: 0%;
    transition: width 0.5s cubic-bezier(.2,.8,.2,1);
  }

  /* ============ NOTES TAB ============ */
  .note-form {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
    align-items: stretch;
  }
  /* Category pills sit on their own full-width row above the input */
  .note-cat-pills { flex-basis: 100%; margin-bottom: 0.15rem; }
  .note-form input[type="text"] {
    flex: 1 1 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .note-form input[type="text"]:focus {
    border-color: var(--pink);
  }
  .note-checkbox-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.8rem;
    border: var(--border);
    background: var(--green-soft);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--green);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    user-select: none;
  }
  .note-checkbox-toggle input { margin: 0; accent-color: var(--pink); cursor: pointer; }
  .note-checkbox-toggle:hover { background: var(--green); color: var(--white); }
  .note-checkbox-toggle:has(input:checked) { background: var(--pink-soft); color: var(--pink-deep); border-color: var(--pink); }
  .note-add-btn {
    padding: 0.65rem 1.1rem;
    background: var(--green);
    color: var(--white);
    font-weight: 700;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    border: var(--border);
    transition: background 0.15s, border-color 0.15s, transform 0.12s, box-shadow 0.15s;
    flex: 1;
  }
  .note-add-btn:hover {
    background: var(--pink);
    border-color: var(--pink);
    transform: translate(-1px, -1px);
    box-shadow: 3px 3px 0 var(--green);
  }

  .notes-list {
    display: flex;
    flex-direction: column;
  }
  .note-item {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--green-soft);
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
  }
  .note-item:last-child { border-bottom: none; }
  .note-check-slot {
    width: 1.4rem;
    height: 1.4rem;
    flex-shrink: 0;
    margin-top: 0.1rem;
  }
  .note-check-slot.none { background: transparent; }
  .note-check-slot button {
    width: 100%; height: 100%;
    border: var(--border);
    background: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: transparent;
    transition: all 0.18s;
    cursor: pointer;
    padding: 0;
  }
  .note-check-slot button:hover { border-color: var(--pink); box-shadow: 2px 2px 0 var(--pink); }
  .note-item.done .note-check-slot button {
    background: var(--green);
    border-color: var(--green);
    color: var(--white);
  }
  .note-bullet {
    color: var(--pink);
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1;
    padding-top: 0.2rem;
  }
  .note-body {
    flex: 1;
    min-width: 0;
    font-size: 0.92rem;
    color: var(--ink);
    line-height: 1.5;
    padding-top: 0.15rem;
    word-wrap: break-word;
    white-space: pre-wrap; /* preserve user line breaks in note text */
    cursor: text;
  }
  .note-body:hover {
    background: var(--pink-soft);
  }

  /* Inline edit mode: textarea fills the note body slot */
  .note-edit-input {
    flex: 1;
    min-width: 0;
    font: inherit;
    font-size: 0.92rem;
    color: var(--ink);
    line-height: 1.5;
    padding: 0.4rem 0.5rem;
    background: var(--white);
    border: 1px solid var(--pink);
    resize: vertical;
    min-height: 2.4rem;
  }
  .note-edit-input:focus {
    outline: none;
    border-color: var(--pink-deep);
  }
  .note-item.editing-note {
    background: var(--pink-soft);
  }
  .note-item.done .note-body {
    text-decoration: line-through;
    color: var(--muted);
  }
  .note-delete {
    color: var(--muted);
    font-size: 0.9rem;
    padding: 0.35rem 0.5rem;
    line-height: 1;
    flex-shrink: 0;
    background: none;
    border: none;
    cursor: pointer;
    transition: color 0.15s;
  }
  .note-delete:hover { color: var(--pink); }

  .notes-empty {
    padding: 1.5rem 1rem;
    border: 1.5px dashed var(--muted);
    text-align: center;
    font-size: 0.9rem;
    color: var(--muted);
    line-height: 1.55;
    display: none;
  }
  .notes-empty.shown { display: block; }

  /* ---- Notes grouping (Must do / Must eat / Must stay / Notes) ---- */
  .notes-group { margin-bottom: 0.25rem; }
  .notes-group-header {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--pink);
    padding: 0.9rem 0 0.35rem;
  }
  .notes-group:first-child .notes-group-header { padding-top: 0.1rem; }
  /* Drag handle for note rows (matches loyalty/family handles) */
  .note-drag {
    color: var(--muted);
    cursor: grab;
    font-size: 1.05rem;
    padding: 0.1rem 0.2rem;
    user-select: none;
    line-height: 1;
    touch-action: none; /* lets SortableJS take the touch before scroll kicks in */
    flex-shrink: 0;
    margin-top: 0.1rem;
    align-self: flex-start;
  }
  .note-drag:hover { color: var(--pink); }
  .note-drag:active { cursor: grabbing; }
  /* SortableJS drag states for note rows (matches Family/Loyalty: a faded
     placeholder that keeps its text). */
  .note-item.sortable-ghost {
    opacity: 0.4;
    background: var(--pink-soft);
  }
  .note-item.sortable-chosen {
    background: var(--white);
  }

  /* ============ PROGRESS BAR END ============ */

  /* ============ ITINERARY TAB ============ */
  .itinerary-empty {
    padding: 1.75rem 1.25rem;
    border: 1.5px dashed var(--muted);
    text-align: center;
    font-size: 0.9rem;
    color: var(--muted);
    line-height: 1.55;
    margin-top: 1rem;
    display: none;
  }
  .itinerary-empty.shown { display: block; }

  .itinerary-day {
    margin-top: 1.75rem;
    margin-bottom: 0.25rem;
    /* Clears the sticky topbar + tab bar when scrollIntoView lands on a day
       (e.g. "open to today" on an in-progress trip), so the day header isn't
       hidden under the sticky chrome. */
    scroll-margin-top: 5rem;
  }
  .itinerary-day-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0 0 0.5rem;
    border-bottom: 1.5px solid var(--green);
    margin-bottom: 0.75rem;
    cursor: pointer;
    user-select: none;
  }
  .itinerary-day-header .day-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.2rem;
    color: var(--green);
    line-height: 1.2;
  }
  .itinerary-day-header .day-title em { color: var(--pink); font-style: normal; }
  .itinerary-day-header .day-meta {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: 0.4rem;
  }
  .itinerary-day-header .day-meta .chev {
    font-size: 0.72rem;
    transition: transform 0.2s;
  }
  .itinerary-day.collapsed .day-meta .chev { transform: rotate(-90deg); }
  .itinerary-day.collapsed .itinerary-day-body { display: none; }

  /* Expand/collapse-all toggle row (Itinerary tab) */
  .itin-controls {
    display: flex;
    justify-content: flex-end;
    margin: 0.75rem 0 0.25rem;
  }
  .itin-expand-toggle {
    background: none;
    border: none;
    color: var(--green);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    cursor: pointer;
    padding: 0.3rem 0;
    -webkit-tap-highlight-color: transparent;
  }
  .itin-expand-toggle:active { color: var(--pink); }
  @media (hover: hover) { .itin-expand-toggle:hover { color: var(--pink); } }

  .itinerary-day-body {
    display: flex;
    flex-direction: column;
  }

  .entry-item {
    padding: 0.85rem 0.5rem 0.85rem 0;
    border-bottom: 1px solid var(--green-soft);
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    position: relative;
  }
  .entry-item:last-child { border-bottom: none; }
  .entry-time {
    flex-shrink: 0;
    width: 3.5rem;
    padding-top: 0.15rem;
    font-family: 'Open Sans', sans-serif;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--pink);
    letter-spacing: 0.02em;
    text-align: right;
  }
  .entry-time.none { color: var(--muted); font-weight: 500; font-style: italic; }

  .entry-main {
    flex: 1;
    min-width: 0;
    padding-right: 1.75rem;
  }
  .entry-type-tag {
    display: inline-block;
    font-size: 0.58rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--green);
    background: var(--green-soft);
    border: 1px solid var(--green);
    padding: 0.15rem 0.5rem;
    margin-bottom: 0.35rem;
  }
  .entry-type-tag.flight { color: var(--pink-deep); background: var(--pink-soft); border-color: var(--pink); }
  .entry-type-tag.stay { }
  .entry-type-tag.activity { }
  .entry-type-tag.transfer { color: var(--muted); background: transparent; border-color: var(--muted); }
  .entry-type-tag.meal { color: var(--muted); background: transparent; border-color: var(--muted); }
  .entry-type-tag.note { color: var(--muted); background: transparent; border-color: var(--muted); }

  .entry-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
    line-height: 1.25;
    margin-bottom: 0.15rem;
    word-wrap: break-word;
  }
  .entry-details {
    font-size: 0.82rem;
    color: var(--muted);
    line-height: 1.55;
    margin-top: 0.35rem;
  }
  .entry-details .detail-line {
    display: flex;
    gap: 0.4rem;
    align-items: flex-start;
  }
  .entry-details .detail-line strong {
    color: var(--green);
    font-weight: 700;
    flex-shrink: 0;
  }
  /* Tap a flight number to check its live status on Google (free convenience).
     Label stays in the normal text color; the pink arrow is the tap cue. */
  .flight-status-link {
    color: inherit;
    text-decoration: none;
  }
  .flight-status-link .flight-status-ext {
    color: var(--pink);
    font-size: 0.82em;
    margin-left: 1px;
  }
  .flight-status-link:hover,
  .flight-status-link:focus-visible {
    text-decoration: underline;
    text-decoration-color: var(--pink);
    text-underline-offset: 2px;
  }
  /* Per-day notes (free): borderless, prose-like text box at the top of a day. */
  .day-note {
    display: block;
    width: 100%;
    box-sizing: border-box;
    border: none;
    background: transparent;
    resize: none;
    overflow: hidden;
    font-family: inherit;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--ink);
    padding: 0.1rem 0 0.55rem;
    margin: 0;
  }
  .day-note::placeholder { color: var(--muted); font-style: italic; }
  .day-note:focus { outline: none; }
  /* "Open in Maps" (Pro). Free users see the locked variant with the pink padlock. */
  .entry-maps-link {
    display: inline-flex;
    align-items: center;
    background: none;
    border: none;
    padding: 0;
    margin-top: 0.1rem;
    color: var(--pink);
    font: inherit;
    font-size: 0.92em;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
  }
  .entry-maps-link .entry-maps-arrow { margin-left: 2px; font-size: 0.85em; }
  .entry-maps-link:hover, .entry-maps-link:focus-visible { text-decoration: underline; }
  .entry-maps-link.locked::after {
    content: '';
    display: inline-block;
    width: 0.9em; height: 0.9em;
    margin-left: 0.4em;
    vertical-align: -0.12em;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d81159' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='11' width='14' height='10' rx='1.5'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") no-repeat center / contain;
  }
  /* Inline SVG icon replacements for the old emoji/glyph indicators.
     Inherits color via currentColor so it picks up the surrounding text color
     (including the cancel-by urgency variants of detail-line). */
  .ui-icon {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--green);
    width: 1em;
    height: 1.2em;
    /* Align the icon's optical center with the first line of adjacent text */
    transform: translateY(0.15em);
  }
  .ui-icon svg {
    width: 100%;
    height: 100%;
  }
  /* In urgency-colored detail-lines, the icon should match the line's color */
  .entry-details .detail-line.cancel-far .ui-icon,
  .entry-details .detail-line.cancel-near .ui-icon,
  .entry-details .detail-line.cancel-soon .ui-icon,
  .entry-details .detail-line.cancel-urgent .ui-icon { color: inherit; }

  /* Cancel-by line: color reflects urgency. Past = muted. Far away = muted gray.
     7-14 days = green (informational). 3-7 days = pink. <3 days = pink-deep with weight. */
  .entry-details .detail-line.cancel-by strong { color: var(--muted); }
  .entry-details .detail-line.cancel-far { color: var(--muted); }
  .entry-details .detail-line.cancel-near { color: var(--green); font-weight: 600; }
  .entry-details .detail-line.cancel-near strong { color: var(--green); }
  .entry-details .detail-line.cancel-soon { color: var(--pink); font-weight: 600; }
  .entry-details .detail-line.cancel-soon strong { color: var(--pink); }
  .entry-details .detail-line.cancel-urgent { color: var(--pink-deep); font-weight: 700; }
  .entry-details .detail-line.cancel-urgent strong { color: var(--pink-deep); }
  .entry-details .detail-line.cancel-past { color: var(--muted); font-style: italic; }

  .entry-menu {
    position: absolute;
    top: 0.65rem;
    right: 0;
    padding: 0.35rem 0.55rem;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1;
    background: none;
    border: none;
    cursor: pointer;
  }
  .entry-menu:hover { color: var(--pink); }

  .overnight-row {
    padding: 0.55rem 0 0.75rem;
    font-size: 0.72rem;
    font-style: italic;
    color: var(--muted);
    border-top: 1px dashed var(--green);
    margin-top: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  /* Bed icon inside .overnight-row is now rendered inline via icon('bed') in JS.
     Style the wrapper so the icon sizes/aligns with the muted text. */
  .overnight-row .ui-icon {
    color: var(--muted);
    width: 1.1em;
    height: 1.1em;
    transform: translateY(0.05em);
  }
  /* Continuation row for multi-day activities on days after the start.
     Mirrors .overnight-row visually so the user reads "this is a span" at
     a glance. Tappable to open the underlying entry. */
  .continuation-row {
    padding: 0.55rem 0;
    font-size: 0.78rem;
    color: var(--muted);
    border-top: 1px dashed var(--green-soft);
    display: flex;
    align-items: center;
    gap: 0.55rem;
    cursor: pointer;
  }
  .continuation-row:hover { color: var(--green); }
  .continuation-row .ui-icon {
    color: var(--muted);
    width: 1.05em;
    height: 1.05em;
    flex-shrink: 0;
  }
  .continuation-row .continuation-title {
    font-weight: 600;
    color: var(--green);
  }
  .continuation-row .continuation-meta {
    font-size: 0.72rem;
    color: var(--muted);
    letter-spacing: 0.02em;
  }
  /* Flight-arrival marker — leads the day a red-eye/long-haul actually lands.
     Tappable to open the originating flight. Plane icon in the flight accent;
     arrival time pushed to the right like a timed event. */
  .arrival-row {
    padding: 0.5rem 0;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.82rem;
    color: var(--muted);
    cursor: pointer;
    border-bottom: 1px dashed var(--green-soft);
    margin-bottom: 0.5rem;
  }
  .arrival-row:hover { color: var(--green); }
  .arrival-row .ui-icon {
    color: var(--pink);
    width: 1.05em;
    height: 1.05em;
    flex-shrink: 0;
  }
  .arrival-row .arrival-dest { font-weight: 600; color: var(--green); }
  .arrival-row .arrival-time {
    margin-left: auto;
    color: var(--green);
    font-weight: 600;
  }
  /* Sub-label inside a multi-day block — slightly smaller than the main
     field label since these sit under "Multi-day? (optional)". */
  .activity-multiday-block .sublabel {
    font-size: 0.7rem;
    color: var(--muted);
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0.04em;
  }
  .activity-multiday-label {
    font-weight: 700;
    color: var(--green);
  }

  /* ============ ENTRY MODAL STYLING ============ */
  .type-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
  }
  .type-pill {
    padding: 0.55rem 0.9rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
  }
  .type-pill:hover { background: var(--green-soft); }
  .type-pill.active {
    background: var(--green);
    color: var(--white);
  }

  .form-row {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
  }
  .form-row .form-field { margin-bottom: 1.1rem; }
  @media (max-width: 460px) {
    .form-row { flex-direction: column; gap: 0; }
    .form-row .form-field { width: 100%; }
    /* Opt-out for rows holding short inputs (times, single numbers) where
       two columns genuinely fit even on narrow phones. Apply via the
       `.compact` modifier alongside `.form-row`. */
    .form-row.compact { flex-direction: row; gap: 0.75rem; }
    .form-row.compact .form-field { width: auto; }
    /* Flight day/time row keeps its 2-line shape on phones too (see below). */
    #entry-day-time-row.flight-mode { flex-direction: row; }
    #entry-day-time-row.flight-mode > .form-field { width: auto; }
  }
  /* Flight day/time row: trip Day on its own line, then Departs + Arrives (+ the
     landing-day offset) together on one compact line — keeps the two times
     side-by-side instead of stacking into four lines on a phone. Toggled by JS
     (setEntryType adds .flight-mode for Flight entries only). The Day field
     carries an inline flex:1.5, so !important is needed to force it full-width. */
  #entry-day-time-row.flight-mode { flex-wrap: wrap; }
  #entry-day-time-row.flight-mode > .form-field:first-child { flex: 1 1 100% !important; }
  /* The cost form's currency+amount compact row zeroes its children's
     margins (so the picker docks flush with Amount), which collapses the
     row's bottom spacing. Restore the standard 1.1rem so CREDIT APPLIED
     below sits at the normal field distance. Scoped to .cost-fields so the
     Stay check-in/out compact row (in .details-group) keeps its own spacing. */
  .cost-fields .form-row.compact { margin-bottom: 1.1rem; }

  /* Credit applied is a special case: it's a .form-field wrapping a .form-row of inputs
     with a single label above and a single hint below. Without overrides, the nested
     .form-field margin + the .form-row margin stack and push the hint text far below
     where other field hints sit. Zero out the inner spacing so it matches the rest. */
  .credit-applied-wrap .form-row { margin-bottom: 0; }
  .credit-applied-wrap .form-row .form-field { margin-bottom: 0; }

  /* Helper line above the Mixed payment fields. Tells the user they can fill in any
     combination of cash/points/FNC. Visually subtle, not a heavy banner. */
  .mixed-helper {
    font-size: 0.78rem;
    color: var(--green);
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
    padding: 0.55rem 0.75rem;
    margin-bottom: 0.85rem;
    line-height: 1.45;
  }

  .form-field .opt {
    color: var(--muted);
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.7rem;
    margin-left: 0.25rem;
  }

  .form-field input[type="time"] {
    width: 100%;
    padding: 0.75rem 0.85rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .form-field input[type="time"]:focus { border-color: var(--pink); box-shadow: 3px 3px 0 var(--pink); }

  .details-toggle {
    width: 100%;
    padding: 0.8rem 1rem;
    border: var(--border);
    background: var(--green-soft);
    color: var(--green);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    cursor: pointer;
    text-align: left;
    transition: background 0.15s, color 0.15s, transform 0.12s, box-shadow 0.15s;
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    box-shadow: 3px 3px 0 var(--green);
  }
  .details-toggle:hover {
    background: var(--green);
    color: var(--white);
    transform: translate(-1px, -1px);
    box-shadow: 4px 4px 0 var(--pink);
  }
  .details-toggle .chev {
    color: var(--pink);
    font-size: 1rem;
    margin-right: 0.5rem;
    display: inline-block;
    transition: transform 0.2s;
  }
  .details-toggle:hover .chev { color: var(--white); }
  .details-toggle.expanded .chev { transform: rotate(90deg); }
  .details-toggle .label-text { flex: 1; }
  .details-toggle .hint-tag {
    font-size: 0.62rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--muted);
    font-style: italic;
  }
  .details-toggle:hover .hint-tag { color: var(--green-soft); }
  .details-toggle.expanded .hint-tag { display: none; }

  .details-section {
    display: none;
    padding: 0 0 0.5rem;
  }
  .details-section.shown { display: block; animation: slideIn 0.25s ease; }

  /* Flight layover toggle: a checkbox row that reveals additional leg fields below */
  .flight-layover-toggle {
    margin: 0.4rem 0 0.6rem;
    padding: 0.7rem 0.75rem;
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
  }
  .flight-layover-toggle .checkbox-row {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    cursor: pointer;
    font-size: 0.88rem;
    color: var(--green);
    font-weight: 600;
    margin-bottom: 0;
  }
  .flight-layover-toggle .checkbox-row input[type="checkbox"] {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--pink);
    cursor: pointer;
    margin: 0;
  }
  .flight-layover-toggle .hint {
    margin-top: 0.45rem;
    font-size: 0.74rem;
    color: var(--muted);
    line-height: 1.4;
  }

  /* Container for connecting legs. Each leg is a card with its own labeled fields. */
  .flight-legs-container {
    margin-top: 0.3rem;
    margin-bottom: 0.7rem;
  }
  .flight-legs-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .flight-leg-card {
    border: 1px solid var(--green-soft);
    background: var(--white);
    padding: 0.85rem 0.85rem 0.5rem;
    position: relative;
  }
  .flight-leg-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
  }
  .flight-leg-card-title {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--pink-deep);
    font-weight: 700;
  }
  .flight-leg-remove {
    background: none;
    border: none;
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    cursor: pointer;
  }
  .flight-leg-remove:hover { color: var(--pink); }
  .add-leg-btn {
    margin-top: 0.55rem;
    width: 100%;
    background: var(--white);
    color: var(--green);
    border: 1px dashed var(--green);
    padding: 0.65rem;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
  }
  .add-leg-btn:hover {
    background: var(--green-soft);
  }

  /* Multi-leg flight display in the itinerary day list */
  .entry-multi-leg-route {
    font-size: 0.74rem;
    color: var(--muted);
    margin-top: 0.2rem;
    letter-spacing: 0.04em;
    font-weight: 500;
  }
  .entry-multi-leg-route .arrow {
    color: var(--pink);
    margin: 0 0.2rem;
  }
  /* Multi-leg flight detail row (in expanded entry view) */
  .flight-leg-detail {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.45rem 0.6rem;
    border-left: 2px solid var(--pink-soft);
    margin: 0.3rem 0 0.3rem 0.3rem;
    font-size: 0.84rem;
    color: var(--text);
  }
  .flight-leg-detail .leg-label {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--pink-deep);
    font-weight: 700;
  }
  .flight-leg-detail .leg-route {
    font-weight: 600;
    color: var(--green);
  }
  .flight-leg-detail .leg-times {
    font-size: 0.78rem;
    color: var(--muted);
  }
  .flight-leg-detail .leg-flight {
    font-size: 0.76rem;
    color: var(--muted);
    font-style: italic;
  }
  .flight-layover-info {
    font-size: 0.74rem;
    color: var(--pink-deep);
    font-style: italic;
    margin: 0.2rem 0 0.2rem 0.6rem;
    padding-left: 0.6rem;
    border-left: 2px dotted var(--pink-soft);
  }

  /* ============ BUCKET LIST ============ */
  .bucketlist-hero {
    /* Tightened to match home/passport/wishlist hero padding. */
    padding: 1.25rem 1.25rem 1rem;
    border-bottom: var(--border);
  }
  .bucketlist-hero h1 {
    font-size: clamp(1.75rem, 6.5vw, 2.4rem);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
  }
  .bucketlist-hero p {
    color: var(--muted);
    font-size: 0.92rem;
    max-width: 36em;
  }

  .bl-stat-wrap {
    padding: 0.85rem 1.25rem 0.85rem;
    border-bottom: 1px solid var(--green-soft);
  }
  .bl-stat-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 0.6rem;
    gap: 1rem;
  }
  .bl-stat-num {
    font-family: 'Young Serif', Georgia, serif;
    font-size: clamp(1.6rem, 6vw, 2.1rem);
    color: var(--green);
    line-height: 1;
    letter-spacing: -0.01em;
  }
  .bl-stat-pct {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--pink);
  }
  .bl-stat-track {
    height: 10px;
    border: var(--border);
    background: var(--green-soft);
    overflow: hidden;
    margin-bottom: 0.75rem;
  }
  .bl-stat-fill {
    height: 100%;
    background: var(--pink);
    width: 0%;
    transition: width 0.6s cubic-bezier(.2,.8,.2,1);
  }
  .bl-stat-sub {
    font-size: 0.72rem;
    color: var(--muted);
    font-style: italic;
  }
  .bl-stat-continents {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.4rem;
  }
  .continent-chip {
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--green-soft);
    background: var(--white);
  }
  .continent-chip strong {
    color: var(--green);
    font-weight: 700;
  }
  .continent-chip.any strong { color: var(--pink); }

  .bl-controls {
    padding: 1rem 1.25rem 0.75rem;
    display: flex;
    gap: 0.5rem;
    align-items: center;
    position: sticky;
    /* Build 35: top updated to match the new tightened topbar height (1.6rem)
       plus tabs height (3rem). Previously had stale 3.5rem topbar assumption
       which left a visible gap; content scrolled through it. */
    top: calc(1.6rem + env(safe-area-inset-top) + 3rem);
    background: var(--white);
    z-index: 30;
    border-bottom: 1px solid var(--green-soft);
    flex-wrap: wrap;
  }
  .bl-search {
    flex: 1 1 180px;
    min-width: 0;
    padding: 0.6rem 0.75rem;
    font: 400 1rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  .bl-search:focus {
    border-color: var(--pink);
    box-shadow: 3px 3px 0 var(--pink);
  }
  .bl-filter-btn {
    padding: 0.55rem 0.85rem;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
  }
  .bl-filter-btn:hover { background: var(--green-soft); }
  .bl-filter-btn.active {
    background: var(--green);
    color: var(--white);
  }

  .bl-list {
    padding: 0.5rem 0 2rem;
  }
  .bl-item {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--green-soft);
    cursor: pointer;
    transition: background 0.12s;
    position: relative;
  }
  .bl-item:hover {
    background: var(--green-soft);
  }
  .bl-item-check {
    flex-shrink: 0;
    width: 1.4rem;
    height: 1.4rem;
    border: var(--border);
    background: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: transparent;
    transition: all 0.18s;
  }
  .bl-item.checked .bl-item-check {
    background: var(--pink);
    border-color: var(--pink);
    color: var(--white);
  }
  .bl-item-body {
    flex: 1;
    min-width: 0;
  }
  .bl-item-name {
    font-size: 0.95rem;
    color: var(--ink);
    line-height: 1.25;
    font-weight: 500;
  }
  .bl-item.checked .bl-item-name {
    color: var(--green);
    font-weight: 600;
  }
  .bl-item-meta {
    font-size: 0.72rem;
    color: var(--muted);
    margin-top: 0.15rem;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .bl-item-meta .year {
    color: var(--pink-deep);
    font-weight: 700;
  }
  .bl-item-meta .notes {
    font-style: italic;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 60vw;
  }
  .bl-item-edit {
    flex-shrink: 0;
    color: var(--muted);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    padding: 0.35rem 0.5rem;
    opacity: 0;
    transition: opacity 0.12s;
  }
  .bl-item:hover .bl-item-edit,
  .bl-item.checked .bl-item-edit { opacity: 1; }
  .bl-item-edit:hover { color: var(--pink); }

  .bl-empty {
    padding: 2rem 1.5rem;
    text-align: center;
    color: var(--muted);
    font-size: 0.88rem;
    font-style: italic;
  }

  /* ============ WISHLIST VIEW ============ */
  .wishlist-hero {
    padding: 1.25rem 1.25rem 1rem;
    border-bottom: var(--border);
  }
  .wishlist-hero h1 {
    font-size: clamp(1.75rem, 6.5vw, 2.4rem);
    line-height: 1.05;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
  }
  .wishlist-hero p {
    color: var(--muted);
    font-size: 0.92rem;
    max-width: 36em;
  }

  #wishlist-content {
    padding: 1.75rem 1.25rem 0;
  }

  /* Wraps "Add a wishlist trip" so it has the same horizontal padding as
     the "Add a family member" and "Add to itinerary" buttons elsewhere */
  .wishlist-add-wrap {
    padding: 0 1.25rem 2rem;
  }

  .wishlist-year-block {
    margin-bottom: 2rem;
  }
  .wishlist-year-header {
    display: flex;
    align-items: baseline;
    gap: 0.7rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid var(--green);
    margin-bottom: 0.85rem;
  }
  .wishlist-year-num {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.7rem;
    color: var(--green);
    line-height: 1;
  }
  .wishlist-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.75rem;
    align-items: start;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--border-color, #E8EBE9);
  }
  .wishlist-row:last-child { border-bottom: none; }

  .wishlist-period {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--green);
    background: var(--green-soft);
    padding: 0.35rem 0.55rem;
    white-space: nowrap;
    align-self: flex-start;
    margin-top: 0.18rem;
  }

  .wishlist-body {
    min-width: 0;
  }
  .wishlist-destination {
    font-size: 1rem;
    line-height: 1.35;
    color: var(--text);
    margin-bottom: 0.2rem;
  }
  .wishlist-destination.brainstorm {
    font-style: italic;
    color: var(--muted);
  }
  .wishlist-status-tag {
    display: inline-block;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    padding: 0.18rem 0.45rem;
    margin-left: 0.4rem;
    vertical-align: 1px;
  }
  .wishlist-status-tag.brainstorm {
    color: var(--muted);
    background: transparent;
    border: 1px dashed var(--muted);
  }
  .wishlist-status-tag.locked {
    color: var(--pink-deep);
    background: var(--pink-soft);
    border: 1px solid var(--pink);
  }
  .wishlist-notes {
    font-size: 0.82rem;
    color: var(--muted);
    line-height: 1.5;
    margin-top: 0.25rem;
  }

  /* Each labeled section in a wishlist card (Must do, Must eat, Must stay, Notes).
     Label sits to the left, text wraps to the right. Compact + scannable. */
  .wishlist-section {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.35rem 0.6rem;
    margin-top: 0.4rem;
    align-items: baseline;
  }
  .wishlist-section-label {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--green);
    font-weight: 700;
    white-space: nowrap;
    line-height: 1.4;
  }
  .wishlist-section-text {
    font-size: 0.83rem;
    color: var(--text);
    line-height: 1.5;
    white-space: pre-wrap; /* preserve user line breaks in textarea content */
  }

  /* List-builder UI for must-dos / must-eats / must-stays inside the wishlist modal.
     Each list shows existing items as removable chips; users add via the input row below. */
  .must-list {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0.5rem;
  }
  .must-list:empty {
    display: none; /* hide the gap entirely when there are no items yet */
  }
  .must-list-item {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.4rem;
    align-items: center;
    padding: 0.5rem 0.65rem;
    background: var(--white);
    border: 1px solid var(--green-soft);
    font-size: 0.88rem;
    color: var(--text);
    line-height: 1.35;
  }
  .must-list-item-text {
    word-break: break-word;
    cursor: text;
  }
  .must-list-item-remove {
    background: none;
    border: none;
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1;
    padding: 0.15rem 0.4rem;
    cursor: pointer;
  }
  .must-list-item-remove:hover { color: var(--pink); }

  /* Inline edit mode: textarea spans the whole row */
  .must-list-item.editing {
    grid-template-columns: 1fr;
    background: var(--pink-soft);
    border-color: var(--pink);
  }
  .must-list-item.editing .must-list-edit-input {
    width: 100%;
    border: 1px solid var(--pink);
    background: var(--white);
    padding: 0.4rem 0.55rem;
    font: inherit;
    font-size: 0.88rem;
    color: var(--text);
    line-height: 1.35;
    resize: vertical;
    min-height: 2.2rem;
  }
  .must-list-item.editing .must-list-edit-input:focus {
    outline: none;
    border-color: var(--pink-deep);
  }

  /* The "Add a must-do" input row */
  .must-add-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.4rem;
    align-items: stretch;
  }
  .must-add-row input {
    /* inherits .form-field input styling, just reduces margin */
    margin: 0;
  }
  .must-add-btn {
    background: var(--green);
    color: var(--white);
    border: 1px solid var(--green);
    padding: 0 0.95rem;
    font-size: 0.84rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    white-space: nowrap;
  }
  .must-add-btn:hover {
    background: var(--green-soft);
    color: var(--green);
  }
  .must-add-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  .wishlist-row-menu {
    background: none;
    border: none;
    color: var(--muted);
    font-size: 0.95rem;
    padding: 0.35rem 0.45rem;
    cursor: pointer;
    align-self: flex-start;
    line-height: 1;
  }
  .wishlist-row-menu:hover { color: var(--pink); }

  /* iCloud backup status (Phase B) — shown only on iOS at the top of the
     backup modal. Green = protected; amber = iCloud off / not signed in. */
  .icloud-status {
    margin: 1rem 0 1.25rem;
    padding: 0.85rem 1.1rem;
    background: var(--green-soft);
    border: var(--border);
    font-size: 0.88rem;
    color: var(--green);
    line-height: 1.5;
  }
  .icloud-status strong { display: block; font-weight: 700; margin-bottom: 0.2rem; }
  .icloud-status span { display: block; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }
  .icloud-status a { color: var(--pink); font-weight: 700; text-decoration: underline; }
  .icloud-status.checking { color: var(--muted); }
  .icloud-status.warn {
    background: var(--amber-soft);
    border-color: var(--amber);
    color: var(--amber);
  }
  .icloud-status.warn span { color: var(--amber); }
  .backup-stats {
    margin: 1rem 0 1.5rem;
    padding: 1rem 1.1rem;
    background: var(--green-soft);
    border: var(--border);
    font-size: 0.88rem;
    color: var(--green);
    line-height: 1.7;
  }
  .backup-stats .row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
  }
  .backup-stats .row strong {
    color: var(--green);
    font-weight: 700;
  }
  .backup-stats .row .val {
    font-family: 'Young Serif', Georgia, serif;
    color: var(--pink-deep);
  }
  .backup-stats.empty {
    font-style: italic;
    color: var(--muted);
    text-align: center;
  }

  .backup-actions {
    display: flex;
    gap: 0.75rem;
    margin-bottom: 1rem;
  }
  .backup-actions button {
    flex: 1;
  }
  .backup-restore-heading {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.1rem;
    color: var(--green);
    margin: 1.5rem 0 0.5rem;
    padding-top: 1.25rem;
    border-top: 1px dashed var(--green);
  }
  .backup-restore-body {
    font-size: 0.88rem;
    color: var(--muted);
    margin-bottom: 1rem;
    line-height: 1.55;
  }
  .backup-restore-body strong { color: var(--pink-deep); }

  .backup-status {
    font-size: 0.85rem;
    margin-top: 0.5rem;
    padding: 0.6rem 0.8rem;
    display: none;
  }
  .backup-status.shown { display: block; }
  .backup-status.success {
    color: var(--green);
    background: var(--green-soft);
    border-left: 3px solid var(--green);
  }
  .backup-status.error {
    color: var(--pink-deep);
    background: var(--pink-soft);
    border-left: 3px solid var(--pink);
  }

  /* ============ COSTS TAB ============ */
  .costs-empty {
    padding: 1.75rem 1.25rem;
    border: 1.5px dashed var(--muted);
    text-align: center;
    font-size: 0.9rem;
    color: var(--muted);
    line-height: 1.55;
    margin-top: 1rem;
    display: none;
  }
  .costs-empty.shown { display: block; }

  .cost-item {
    padding: 1rem 0 1rem;
    border-bottom: 1px solid var(--green-soft);
    display: flex;
    gap: 0.85rem;
    align-items: flex-start;
    position: relative;
    background: var(--white);
    transition: background 0.15s;
  }
  .cost-item:last-child { border-bottom: none; }

  .cost-drag-handle {
    flex-shrink: 0;
    width: 1.5rem;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-weight: 700;
    font-size: 0.85rem;
    letter-spacing: -0.1em;
    line-height: 1;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s;
    margin-top: 0.15rem;
  }
  .cost-drag-handle:hover, .cost-drag-handle:active {
    opacity: 1;
    color: var(--pink);
    cursor: grabbing;
  }

  /* SortableJS drag states */
  .cost-item.sortable-ghost {
    opacity: 0.3;
    background: var(--pink-soft);
  }
  .cost-item.sortable-chosen {
    background: var(--green-soft);
  }
  .cost-item.sortable-drag {
    box-shadow: 4px 4px 0 var(--pink);
    background: var(--white);
    cursor: grabbing;
  }
  .cost-pay-tag {
    flex-shrink: 0;
    font-size: 0.58rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--green);
    background: var(--green-soft);
    border: 1px solid var(--green);
    padding: 0.25rem 0.5rem;
    min-width: 3.25rem;
    text-align: center;
  }
  .cost-pay-tag.cash { color: var(--green); background: var(--green-soft); border-color: var(--green); }
  .cost-pay-tag.points { color: var(--pink-deep); background: var(--pink-soft); border-color: var(--pink); }
  .cost-pay-tag.miles { color: var(--pink-deep); background: var(--pink-soft); border-color: var(--pink); }
  .cost-pay-tag.mixed { color: var(--muted); background: transparent; border-color: var(--muted); border-style: dashed; }
  .cost-pay-tag.fnc { color: var(--pink-deep); background: var(--white); border-color: var(--pink-deep); border-style: double; border-width: 3px; padding: 0.15rem 0.5rem; }

  .cost-body {
    flex: 1;
    min-width: 0;
    padding-right: 1.75rem;
  }
  .cost-title {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1rem;
    color: var(--green);
    line-height: 1.25;
    margin-bottom: 0.25rem;
    word-wrap: break-word;
  }
  .cost-amount {
    font-size: 0.9rem;
    color: var(--ink);
    font-weight: 600;
    letter-spacing: 0.01em;
  }
  .cost-amount .sub {
    color: var(--muted);
    font-weight: 500;
    margin-left: 0.35rem;
  }
  .cost-amount .plus {
    color: var(--pink);
    margin: 0 0.3rem;
    font-weight: 700;
  }
  .cost-amount .fnc-details {
    color: var(--pink-deep);
    font-style: italic;
  }
  /* Savings line below the amount: "~$1,200 value · saved $1,150" */
  .cost-savings {
    margin-top: 0.25rem;
    font-size: 0.78rem;
    color: var(--green);
    font-weight: 600;
    letter-spacing: 0.02em;
  }
  /* Credit applied annotation: "− $250 Cap One travel credit" */
  .cost-credit {
    margin-top: 0.2rem;
    font-size: 0.78rem;
    color: var(--pink-deep);
    font-weight: 600;
  }
  .cost-note {
    margin-top: 0.4rem;
    font-size: 0.82rem;
    color: var(--muted);
    line-height: 1.55;
    font-style: italic;
  }

  .cost-menu {
    position: absolute;
    top: 0.7rem;
    right: 0;
    padding: 0.35rem 0.55rem;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1;
    background: none;
    border: none;
    cursor: pointer;
  }
  .cost-menu:hover { color: var(--pink); }

  /* Cost link icon — shows on costs that are linked to an itinerary entry */
  .cost-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.35rem;
    padding: 0.2rem 0.5rem;
    color: var(--green);
    background: var(--green-soft);
    border: 1px solid var(--green);
    font-size: 0.66rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
  }
  .cost-link:hover { background: var(--green); color: var(--white); }
  .cost-link .link-icon { font-size: 0.85rem; line-height: 1; }

  /* Hint shown inside the entry cost section explaining where it lands */
  .entry-cost-hint {
    margin-top: 0.5rem;
    padding: 0.5rem 0.75rem;
    background: var(--green-soft);
    border-left: 2px solid var(--green);
    color: var(--green);
    font-size: 0.78rem;
    line-height: 1.5;
  }

  /* Entry highlight: brief flash when navigating to a linked entry from costs */
  .entry-highlighted {
    animation: entryHighlight 1.6s ease;
  }
  @keyframes entryHighlight {
    0%, 100% { background: transparent; }
    20%, 60% { background: var(--pink-soft); }
  }

  .costs-totals {
    margin-top: 1.75rem;
    padding: 1.25rem 1.2rem;
    border: var(--border);
    background: var(--white);
  }
  .costs-totals .title {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--pink);
    margin-bottom: 0.75rem;
  }
  /* Title + segmented control on one row. Title left, toggle right,
     vertically centered. In this context the title uses tighter letter-
     spacing than the standalone 0.2em so both fit one row on standard
     phones; white-space:nowrap keeps the title from breaking mid-phrase.
     flex-wrap is the last-resort fallback for very narrow screens (SE-class). */
  .costs-totals-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
  }
  .costs-totals-head .title {
    margin-bottom: 0;
    letter-spacing: 0.1em;
    white-space: nowrap;
  }
  /* Segmented control for the converted / by-currency totals view. Only
     rendered when a trip has more than one cash currency. Active segment is
     filled — reuses the tappable look of the payment-type pills. */
  .costs-totals-modes {
    display: inline-flex;
    border: 1px solid var(--green);
    flex: 0 0 auto;
  }
  .ctmode {
    font-size: 0.58rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.32rem 0.55rem;
    background: var(--white);
    color: var(--green);
    border: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  .ctmode + .ctmode { border-left: 1px solid var(--green); }
  .ctmode.active { background: var(--green); color: var(--white); }
  /* Note shown when one or more costs can't be converted (no FX rate yet). */
  .costs-totals-note {
    font-size: 0.74rem;
    line-height: 1.4;
    color: var(--muted);
    background: var(--green-soft);
    border-left: 2px solid var(--pink);
    padding: 0.55rem 0.7rem;
    margin: 0.5rem 0 0.25rem;
  }
  /* ===== v1.2 exchange-rate manager (Costs tab) ===== */
  .costs-rates {
    margin-top: 1rem;
    padding: 1rem 1.2rem 1.1rem;
    border: var(--border);
    background: var(--white);
  }
  .costs-rates-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.15rem;
  }
  .costs-rates-title {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--green);
  }
  .costs-rates-updated {
    font-size: 0.68rem;
    color: var(--muted);
    white-space: nowrap;
  }
  .costs-rates-sub {
    font-size: 0.74rem;
    color: var(--muted);
    margin-bottom: 0.7rem;
  }
  .rate-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0;
    border-top: 1px dashed var(--green-soft);
    flex-wrap: wrap;
  }
  .rate-row-label {
    font-size: 0.9rem;
    color: var(--green);
    font-weight: 600;
    white-space: nowrap;
  }
  .rate-row-input {
    width: 5.5rem;
    padding: 0.4rem 0.5rem;
    font: 400 0.95rem 'Open Sans', sans-serif;
    border: var(--border);
    background: var(--white);
    color: var(--green);
    outline: none;
    text-align: right;
  }
  .rate-row-input:focus { border-color: var(--pink); }
  .rate-row-ccy {
    font-size: 0.9rem;
    color: var(--green);
    white-space: nowrap;
  }
  .rate-row-meta {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
  }
  .rate-source {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
  }
  .rate-source.manual { color: var(--pink); }
  .rate-reset {
    background: none;
    border: none;
    color: var(--green);
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 2px;
    -webkit-tap-highlight-color: transparent;
  }
  .rate-reset:active { color: var(--pink); }
  @media (hover: hover) { .rate-reset:hover { color: var(--pink); } }
  .rate-row.unconvertible .rate-source { color: var(--pink); }
  .costs-totals .row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0.5rem 0;
    border-bottom: 1px dashed var(--green-soft);
    gap: 1rem;
    flex-wrap: wrap;
  }
  .costs-totals .row:last-child { border-bottom: none; }
  .costs-totals .row .label {
    font-size: 0.8rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 600;
  }
  .costs-totals .row .val {
    font-family: 'Young Serif', Georgia, serif;
    font-size: 1.15rem;
    color: var(--green);
    text-align: right;
  }
  .costs-totals .row.points .val,
  .costs-totals .row.miles .val {
    color: var(--pink-deep);
  }
  .costs-totals .row.fnc .val {
    color: var(--pink-deep);
    font-style: italic;
  }
  .costs-totals .row .row-sub {
    flex-basis: 100%;
    font-size: 0.72rem;
    color: var(--muted);
    margin-top: 0.15rem;
    font-style: italic;
    text-align: right;
  }
  /* Brag stats section: "Saved with points", "Credits used", etc.
     Distinguished from the basic totals with a divider and lighter visual weight. */
  .costs-totals .brag-divider {
    height: 0;
    border-top: 2px solid var(--pink-soft);
    margin: 0.85rem 0 0.55rem;
    position: relative;
  }
  .costs-totals .brag-divider::before {
    content: 'WHAT YOU SAVED';
    position: absolute;
    top: -0.55rem;
    left: 0;
    background: var(--white);
    padding-right: 0.6rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--pink);
  }
  .costs-totals .row.savings .label {
    color: var(--green);
  }
  .costs-totals .row.savings .val {
    color: var(--pink);
    font-weight: 700;
  }

  /* Give lists below "add" buttons enough room for the button's offset shadow */
  #costs-wrap,
  #itinerary-wrap,
  #notes-list {
    margin-top: 1.5rem;
  }

  /* Footer tagline */
  .footer {
    padding: 2rem 1.25rem 3rem;
    border-top: var(--border);
    text-align: center;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--muted);
    line-height: 1.6;
  }
  .footer .copy {
    letter-spacing: 0.06em;
    margin-bottom: 0.4rem;
  }
  .footer .links a {
    color: var(--muted);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    cursor: pointer;
  }
  .footer .links a.backup-link {
    color: var(--green);
    font-weight: 600;
  }
  /* When iCloud is auto-syncing, the link becomes an ambient status (no
     underline so it reads as reassurance, but still tappable → backup modal). */
  .footer .links a.backup-link.is-status { text-decoration: none; cursor: pointer; }
  .footer .links a:hover { color: var(--pink); }
  .footer .links .sep { margin: 0 0.5rem; color: var(--green); }

  /* ===== iPad / desktop vertical rhythm (≥760px) =====
     Phone spacing is tight to conserve space; on the big screen those same gaps
     read as compressed, so give the hero more room top + bottom and open up the
     space between the trips and tools sections. Placed at the END of the
     stylesheet so it wins over the base rules above. */
  @media (min-width: 760px) {
    /* Both states — .compact (shown once you have trips) is more specific, so
       list it explicitly or it keeps the tight phone padding. */
    .home-hero,
    .home-hero.compact { padding-top: 2.5rem; padding-bottom: 2rem; }
    .trips-section { padding-bottom: 1.5rem; }
    .tools-section { padding-top: 2rem; }
  }

  /* Small "Share your savings" action at the foot of the Costs savings box. */
  .costs-brag-share {
    display: flex; align-items: center; gap: 0.45rem; width: max-content;
    margin: 1.1rem 0 0.1rem auto; padding: 0.45rem 0.8rem;
    border: var(--border); background: var(--white); color: var(--pink-deep);
    font: 700 0.72rem 'Open Sans', sans-serif; text-transform: uppercase;
    letter-spacing: 0.1em; cursor: pointer; transition: background 0.15s, color 0.15s;
  }
  .costs-brag-share:hover, .costs-brag-share:active { background: var(--pink); color: var(--white); }
  .costs-brag-share svg { width: 15px; height: 15px; }

  /* ===== Brag card share modal ===== */
  .brag-preview { text-align: center; margin: 0.25rem auto 1rem; }
  .brag-preview img {
    display: block; margin: 0 auto; max-width: 200px; max-height: 300px;
    width: auto; height: auto; box-shadow: 0 6px 24px rgba(0,71,69,0.18);
  }
  .brag-format { display: flex; border: var(--border); width: max-content; margin: 0 auto 0.85rem; }
  .brag-fmt-btn {
    padding: 0.5rem 1.2rem; border: none; background: var(--white); color: var(--green);
    font: 700 0.72rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.1em; cursor: pointer;
  }
  .brag-fmt-btn + .brag-fmt-btn { border-left: var(--border); }
  .brag-fmt-btn.active { background: var(--green); color: var(--white); }
  .brag-cash-toggle {
    display: flex; align-items: center; justify-content: center; gap: 0.5rem;
    font-size: 0.85rem; color: var(--muted); margin-bottom: 1.1rem; cursor: pointer;
  }
  .brag-cash-toggle input { width: 1.05rem; height: 1.05rem; accent-color: var(--pink); flex: none; }
  /* Softer shadow than the global pink offset for the image-preview modal. */
  .brag-modal { box-shadow: 0 12px 44px rgba(0,71,69,0.22); }
  /* Stories-only: add/change the trip photo + the tap-to-blur hint. The photo
     button is deliberately smaller/lighter than the Square/Stories toggle. */
  .brag-photo-row { display: flex; align-items: center; justify-content: center; gap: 0.55rem; flex-wrap: wrap; margin: 0 auto 0.9rem; }
  .brag-photo-btn {
    display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.32rem 0.7rem;
    border: var(--border); background: var(--white); color: var(--green);
    font: 700 0.6rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.06em; cursor: pointer;
  }
  .brag-photo-btn:hover, .brag-photo-btn:active { background: var(--green); color: var(--white); }
  /* Full-width so it drops to its own line BELOW the buttons (keeps the two
     buttons centered whether or not the hint is showing). */
  .brag-blur-hint { font-size: 0.76rem; color: var(--muted); flex-basis: 100%; text-align: center; }
  .brag-preview img.brag-tappable { cursor: crosshair; }
  /* The class display rules above override the bare [hidden] attribute, so
     restore it for these elements (used to show/hide per format + photo state). */
  .brag-photo-row[hidden], .brag-photo-btn[hidden] { display: none; }
  /* Face-cover style picker (Pixelate / emoji). */
  .brag-treatments { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.4rem; margin: 0 auto 1rem; }
  .brag-treatments[hidden] { display: none; }
  .brag-treat { padding: 0.32rem 0.55rem; border: var(--border); background: var(--white); color: var(--green); cursor: pointer; font: 700 0.64rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.05em; line-height: 1.1; }
  .brag-treat[data-treat]:not([data-treat="pixel"]) { font-size: 1.05rem; padding: 0.12rem 0.38rem; text-transform: none; letter-spacing: 0; }
  .brag-treat.active { background: var(--green); color: var(--white); border-color: var(--green); }

  /* ===== Account / Pro sign-in modal ===== */
  .account-privacy-note { font-size: 0.8rem; color: var(--muted); }
  .account-agree { text-align: center; font-size: 0.78rem; color: var(--muted); margin: 0.85rem 0 0.1rem; line-height: 1.5; }
  .account-agree a { color: var(--pink); text-decoration: underline; }
  /* "Already bought Pro? Sign in to restore it" — its own pink line under the
     checkout button so returning buyers don't think they have to pay again. */
  #modal-account .account-restore-line { text-align: center; margin: 0.8rem 0 0.4rem; font-size: 0.9rem; color: var(--pink); font-weight: 600; }
  #modal-account .account-restore-line a { color: var(--pink); font-weight: 700; text-decoration: underline; }
  /* Spotify-style single Pro plan card: badge, price, feature list, then the
     web checkout or the link-out button. Soft, no pink offset shadow. */
  .pro-plan-card { border: var(--border); border-radius: 4px; background: var(--white); padding: 1.1rem 1.15rem; margin: 0.3rem 0 0.6rem; }
  .pro-plan-badge { display: inline-block; background: var(--pink-soft); color: var(--pink-deep); font: 700 0.66rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.08em; padding: 0.25rem 0.55rem; border-radius: 3px; margin-bottom: 0.7rem; }
  .pro-plan-name { font: 700 0.74rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); }
  .pro-plan-price { font-family: 'Young Serif', Georgia, serif; font-size: 2.1rem; color: var(--green); line-height: 1.05; }
  .pro-plan-per { font-family: 'Open Sans', sans-serif; font-size: 0.9rem; color: var(--muted); }
  .pro-plan-sub { font-size: 0.82rem; color: var(--muted); margin-top: 0.15rem; }
  .pro-plan-features { list-style: none; margin: 0.95rem 0 0; padding: 0; }
  .pro-plan-features li { position: relative; padding-left: 1.5rem; margin-bottom: 0.5rem; font-size: 0.88rem; color: var(--green); line-height: 1.4; }
  .pro-plan-features li::before { content: ''; position: absolute; left: 0; top: 0.12em; width: 1em; height: 1em; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d81159' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") no-repeat center / contain; }
  /* The first-trip nudge reuses this list inside a center-aligned modal; make it
     a centered block with left-aligned rows so each checkmark hugs its label.
     Also tighten the gap above the list: the base modal-sub margin-bottom (1.4rem)
     and the list's margin-top (0.95rem) stack too large, leaving the "Pro adds:"
     line floating far from the first feature. */
  #modal-pro-nudge .modal-sub { margin-bottom: 0.4rem; }
  #modal-pro-nudge .pro-plan-features { display: inline-block; text-align: left; margin-top: 0.3rem; }
  /* The base .modal h2 reserves padding-right for the close button, which pushes a
     centered title left of true center; add matching left padding to re-center it. */
  #modal-pro-nudge #pro-nudge-title { padding-left: 2rem; }
  /* Small print under the features: what's coming next + the founding price. */
  #modal-pro-nudge .pro-nudge-note { font-size: 0.8rem; line-height: 1.45; color: var(--muted); margin: 0.75rem auto 0; max-width: 340px; }
  #checkout-web, #checkout-native { margin-top: 1rem; }
  #account-checkout-web { display: inline-flex; align-items: center; justify-content: center; }
  .ext-link-icon { width: 0.95em; height: 0.95em; margin-left: 0.45em; vertical-align: -0.12em; }
  .account-status { border: var(--border); padding: 0.9rem 1rem; margin: 0.5rem 0 1rem; font-size: 0.95rem; line-height: 1.5; }
  .account-status .pro-badge {
    display: inline-block; background: var(--pink); color: var(--white);
    font: 700 0.66rem 'Open Sans', sans-serif; text-transform: uppercase;
    letter-spacing: 0.08em; padding: 0.2rem 0.5rem; margin-left: 0.5rem; vertical-align: middle;
  }
  .account-status .pro-badge.free { background: var(--muted); }
  .account-status .account-sub { font-size: 0.82rem; color: var(--muted); }
  .account-msg { margin-top: 0.8rem; font-size: 0.85rem; color: var(--pink-deep); text-align: center; }
  /* Account modal: soft shadow instead of the pink offset (matches .brag-modal). */
  #modal-account .modal { box-shadow: 0 12px 44px rgba(0,71,69,0.22); }
  #account-upgrade-row[hidden] { display: none; }
  /* Upgrade button: brand yellow, dark ink for contrast (Megan's pick). */
  #account-upgrade {
    background: #ffbc42; border: var(--border); color: #333333;
  }
  #account-upgrade:hover, #account-upgrade:active {
    background: #f5ad26; border: var(--border); color: #333333;
  }
  /* "Share my year" — center the button under the Year View stats; soft modal shadow. */
  .year-share-wrap { display: flex; justify-content: center; margin: 1rem 0 0.25rem; }
  .year-share-wrap .costs-brag-share { margin: 0; }
  #modal-year .modal { box-shadow: 0 12px 44px rgba(0,71,69,0.22); }

  /* ===== "Where the money went" category breakdown (Costs tab, Pro) ===== */
  .cost-breakdown { border-top: var(--border); margin-top: 1rem; padding-top: 1rem; }
  .cost-breakdown-head {
    font: 700 0.72rem 'Open Sans', sans-serif; text-transform: uppercase;
    letter-spacing: 0.1em; color: var(--green); margin-bottom: 0.3rem;
  }
  .cost-breakdown-sub {
    font: 400 0.8rem 'Open Sans', sans-serif; color: var(--muted);
    line-height: 1.4; margin-bottom: 0.7rem;
  }
  .cost-breakdown-bar { display: flex; height: 14px; width: 100%; overflow: hidden; border: 1px solid var(--green); }
  .cost-breakdown-bar span { display: block; height: 100%; }
  .cost-breakdown-bar span + span { border-left: 1px solid var(--white); }
  .cost-breakdown-legend { margin-top: 0.7rem; display: flex; flex-direction: column; gap: 0.4rem; }
  .cost-cat-row { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; }
  .cost-cat-dot { width: 0.7rem; height: 0.7rem; border-radius: 50%; flex: none; }
  .cost-cat-name { flex: 1; color: var(--ink, #1a2b2a); }
  .cost-cat-val { font-weight: 700; color: var(--green); }
  .cost-cat-pct { width: 2.6rem; text-align: right; color: var(--muted); font-size: 0.82rem; }
  .cost-breakdown.locked .cost-breakdown-teaser { font-size: 0.85rem; color: var(--muted); line-height: 1.5; }
  .cost-breakdown-upgrade { color: var(--pink-deep); font-weight: 700; text-decoration: none; white-space: nowrap; }

  /* ===== Itinerary List ⇄ Calendar view (calendar is Pro) ===== */
  .itin-controls { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
  .itin-view-toggle { display: flex; border: var(--border); }
  .itin-view-btn {
    padding: 0.4rem 0.85rem; border: none; background: var(--white); color: var(--green);
    font: 700 0.68rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.08em; cursor: pointer;
  }
  .itin-view-btn + .itin-view-btn { border-left: var(--border); }
  .itin-view-btn.active { background: var(--green); color: var(--white); }
  .itin-view-btn.locked::after {
    content: '';
    display: inline-block;
    width: 0.9em; height: 0.9em;
    margin-left: 0.34em;
    vertical-align: -0.13em;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d81159' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='11' width='14' height='10' rx='1.5'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") no-repeat center / contain;
  }
  /* Month grid */
  .itin-calendar { display: flex; flex-direction: column; gap: 1.5rem; }
  .cal-month-name { font: 700 0.8rem 'Open Sans', sans-serif; text-transform: uppercase; letter-spacing: 0.08em; color: var(--green); text-align: center; margin-bottom: 0.6rem; }
  .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
  .cal-wd { text-align: center; font: 700 0.6rem 'Open Sans', sans-serif; color: var(--muted); padding-bottom: 0.3rem; }
  .cal-cell { min-height: 46px; border: 1px solid #e8e4dc; box-shadow: none; display: flex; flex-direction: column; align-items: center; padding: 3px 1px; }
  .cal-cell.cal-blank { border: none; box-shadow: none; background: transparent; }
  .cal-cell.cal-out { opacity: 0.35; }
  .cal-cell.cal-trip { background: var(--white); }
  .cal-cell.cal-has { cursor: pointer; transition: background 0.12s; }
  .cal-cell.cal-has:hover, .cal-cell.cal-has:active { background: var(--pink-soft); }
  .cal-cell.cal-today { outline: 2px solid var(--pink); outline-offset: -2px; }
  .cal-num { font: 600 0.72rem 'Open Sans', sans-serif; color: #1a2b2a; }
  .cal-cell.cal-out .cal-num { color: var(--muted); }
  .cal-dots { display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; margin-top: 3px; }
  .cal-dot { width: 5px; height: 5px; border-radius: 50%; }
  .cal-more { font-size: 0.52rem; color: var(--muted); line-height: 1; }

  /* ===== "Shared links" manager (footer → modal) ===== */
  .shared-links-list { margin: 0.25rem 0 0.5rem; max-height: 50vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .shared-links-empty { color: var(--muted); font-size: 0.92rem; line-height: 1.5; margin: 0.5rem 0; }
  .shared-link-row {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.7rem 0; border-bottom: 1px solid var(--green-soft);
  }
  .shared-link-row:last-child { border-bottom: none; }
  .shared-link-info { flex: 1; min-width: 0; }
  .shared-link-name {
    font-weight: 600; color: var(--ink); font-size: 0.98rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .shared-link-meta { color: var(--muted); font-size: 0.8rem; margin-top: 0.1rem; }
  .shared-link-revoke {
    flex-shrink: 0; font: 600 0.82rem 'Open Sans', sans-serif;
    color: var(--pink); background: none; border: 1.5px solid var(--pink);
    border-radius: 999px; padding: 0.35rem 0.85rem; cursor: pointer;
    transition: background 0.12s, color 0.12s;
  }
  .shared-link-revoke:hover:not(:disabled), .shared-link-revoke:active:not(:disabled) { background: var(--pink); color: #fff; }
  .shared-link-revoke:disabled { opacity: 0.6; cursor: default; }

  /* ===== Settings (top-bar gear → grouped sheet) ===== */
  .topbar-gear { background: none; border: none; color: var(--green); padding: 0.25rem; margin: -0.25rem; line-height: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .topbar-gear:active { opacity: 0.55; }
  .settings-label { text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.72rem; font-weight: 700; color: var(--muted); margin: 1.15rem 0 0.1rem; }
  .settings-label:first-of-type { margin-top: 0.4rem; }
  .settings-row { display: flex; align-items: center; gap: 0.75rem; padding: 0.8rem 0; border-bottom: 1px solid var(--green-soft); text-decoration: none; color: var(--ink); }
  .settings-row:last-of-type { border-bottom: none; }
  .settings-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.12rem; }
  .settings-row-title { font-size: 1rem; color: var(--ink); }
  .settings-row-sub { font-size: 0.82rem; color: var(--muted); line-height: 1.35; }
  .settings-chev { color: var(--muted); font-size: 1.15rem; flex-shrink: 0; }
  .settings-social-link { color: var(--green); display: inline-flex; }
  .settings-social-link:active { color: var(--pink); }

  /* App-only disclosure under the Upgrade button: on the App Store / Play
     builds, tapping Upgrade leaves the app for the website checkout, so we say
     so (Apple external-purchase transparency). Hidden on web, where there's no
     "leaving the app". */
  .account-website-note { display: none; }
  body.platform-native .account-website-note { display: block; }
  /* The mirror of the above: the "checkout uses this account's email" line is
     only true on the web, where the in-app Stripe checkout locks the email. On
     app builds the email is typed on the website, so hide it there. */
  body.platform-native .account-web-only-note { display: none; }
