/* ============================================================
   BASE — design tokens, reset, typography, shared components
   TravelPad design language: "field guide, not dashboard".
   Warm paper, deep forest, campfire amber. Everything springs.
   ============================================================ */

/* Fonts load via <link> + preconnect in each page's <head> (no CSS @import chain). */

/* --- Design tokens --- */
:root {
    /* Dark greens used as text; night forest lifts them so they stay readable (C5 web dark, R150). */
    --green-ink-800: var(--green-800);
    --green-ink-900: var(--green-900);
    --green-ink-950: var(--green-950);
    /* Greens — deep forest, richer + moodier than before */
    --green-950: #0e2015;
    --green-900: #1a3425;
    --green-850: #21422e;
    --green-800: #2a5339;
    --green-700: #3e7a54;   /* primary */
    --green-600: #529068;
    --green-300: #8cc7a1;
    --green-200: #b5ddc4;
    --green-100: #d8efe1;
    --green-50:  #eef8f2;

    /* Warm neutrals — sun-bleached paper */
    --brown-900: #26200f;
    --brown-700: #4c3e29;
    --brown-500: #786751;
    --brown-300: #bda887;
    --cream-300: #dbcfb7;
    --cream-200: #efe7d5;
    --cream-100: #f8f3e8;
    --cream-50:  #fefcf7;

    /* Campfire amber — the reward / delight accent */
    --sun-600: #c26a25;
    --sun-500: #e0862f;
    --sun-400: #f2a854;
    --sun-100: #fcefdc;
    --sun-50:  #fef8ee;

    /* Semantic aliases */
    --color-primary:        var(--green-700);
    --color-primary-dark:   var(--green-800);
    --color-primary-light:  var(--green-100);
    --color-accent:         var(--sun-500);
    --color-accent-deep:    var(--sun-600);
    --color-accent-soft:    var(--sun-100);
    --color-bg:             var(--cream-100);
    --color-surface:        var(--cream-50);
    --color-text:           var(--brown-900);
    --color-text-muted:     var(--brown-500);
    --color-border:         var(--cream-300);
    --color-border-soft:    var(--cream-200);
    --color-border-focus:   var(--green-700);
    --color-error:          #93312d;
    --color-error-bg:       #fdf1ef;
    --color-success:        var(--green-700);
    --color-success-bg:     #edf7f0;
    --color-success-border: #b8dfc4;

    /* Shape */
    --radius-sm:  9px;
    --radius-md:  13px;
    --radius-lg:  18px;
    --radius-xl:  26px;

    /* Elevation — layered, warm-tinted, never gray */
    --shadow-xs:  0 1px 2px rgba(38, 32, 15, 0.06);
    --shadow-sm:  0 1px 2px rgba(38, 32, 15, 0.05), 0 2px 6px rgba(38, 32, 15, 0.05);
    --shadow-md:  0 2px 4px rgba(38, 32, 15, 0.05), 0 6px 16px rgba(38, 32, 15, 0.07), 0 12px 32px rgba(38, 32, 15, 0.05);
    --shadow-lg:  0 4px 10px rgba(38, 32, 15, 0.06), 0 16px 40px rgba(38, 32, 15, 0.12), 0 30px 80px rgba(38, 32, 15, 0.10);
    --shadow-primary: 0 3px 8px rgba(42, 83, 57, 0.22), 0 8px 24px rgba(42, 83, 57, 0.26);
    --shadow-accent:  0 3px 8px rgba(194, 106, 37, 0.20), 0 8px 24px rgba(194, 106, 37, 0.24);
    --ring-primary: 0 0 0 3.5px rgba(62, 122, 84, 0.18);
    --ring-accent:  0 0 0 3.5px rgba(224, 134, 47, 0.22);

    /* Motion — springs first, fades last */
    --ease-out:         cubic-bezier(0.22, 1, 0.36, 1);
    --ease-spring:      cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-spring-soft: cubic-bezier(0.3, 1.25, 0.5, 1);
    --ease-swift:       cubic-bezier(0.55, 0, 0.1, 1);
    --duration-fast:    0.16s;
    --duration-base:    0.26s;
    --duration-slow:    0.45s;
    --duration-slower:  0.7s;

    /* Typography */
    --font-display: 'Fraunces', 'Playfair Display', Georgia, serif;
    --font-body:    'Figtree', 'Lato', 'Segoe UI', system-ui, sans-serif;
    /* Third face (C1, R139): Courier Prime only for dates, ticket stubs, mile markers and coordinates. */
    --font-mono:    'Courier Prime', ui-monospace, 'Courier New', monospace;

    /* Ink (C1): headline and "handwritten" text, slightly warmer than brown-900 */
    --ink:          #2c2110;
    --ink-soft:     #4c3e29;
    --color-text-ink: var(--ink);

    /* Reduced shadow scale (C1, docs/cozy-style.md): new surfaces use only these two.
       flat = a hairline, mostly no lift; lift = the one lifted level (menus, sheets, picked-up cards). */
    --shadow-flat:  0 0 0 1px rgba(38, 32, 15, 0.06);
    --shadow-lift:  0 6px 16px -8px rgba(38, 32, 15, 0.22), 0 1px 0 rgba(38, 32, 15, 0.05);

    /* Textures (C1): grain tile, dot grid + contours, tape and stamp inks. Night-forest values below. */
    --tp-grain-url:      url('/images/paper-grain-6f6a1126e7e7d3fb0d5d14919568adb5.png');
    --tp-grain-alpha:    0.04;
    --tp-grain-blend:    multiply;
    --tp-paper-top:      #fefcf7;
    --tp-paper-bottom:   #f3ecdd;
    --tp-paper-dot:      rgba(219, 207, 183, 0.55);
    --tp-paper-contours: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 140' preserveAspectRatio='none' fill='none' stroke='%23cdbf9f' stroke-opacity='.5' stroke-width='1.1' stroke-linecap='round'%3E%3Cpath d='M-11 77C40 67 70 87 110 77S180 65 231 73'/%3E%3Cpath d='M-11 99C40 89 70 109 110 99S180 87 231 95'/%3E%3Cpath d='M-11 121C40 111 70 131 110 121S180 109 231 117'/%3E%3Cellipse cx='172' cy='34' rx='36' ry='18'/%3E%3Cellipse cx='172' cy='34' rx='25' ry='12.6'/%3E%3Cellipse cx='172' cy='34' rx='14.4' ry='7.2'/%3E%3C/svg%3E");
    --tp-tape-fill:      rgba(239, 231, 213, 0.85);
    --tp-stamp-blend:    multiply;

    /* Official account card stock (C4, R148): kraft paper, its hairline and the white slide mount. */
    --tp-kraft:          #efe4cf;
    --tp-kraft-line:     #dccbab;
    --tp-mount:          #fefcf7;

    /* Radius rule (C1, docs/cozy-style.md): pill (999px) only for filter chips, segmented toggles,
       avatars and count badges. Everything that labels something (stamps, "Remixed from", dates,
       categories, menu rows, tags) is a squarer tag on --radius-sm. If unsure, it is a tag. */

    /* Pro brand — deep teal, kept from the original identity */
    --pro-brand:        #0f8f82;
    --pro-brand-mid:    #087896;
    --pro-brand-dark:   #066860;
    --pro-brand-glow:   rgba(15, 143, 130, 0.35);
}

/* --- Night forest (C1 tokens, R137): the website is light-only (R157). These values apply only when a page
   is forced with <html data-theme="dark"> for checks; nothing sets it for visitors. --- */
[data-theme="dark"] {
    --green-ink-800: #b5ddc4;
    --green-ink-900: #d3ecdc;
    --green-ink-950: #e6f4ea;
    --color-bg:             #0e2015;
    --color-surface:        #15291c;
    --color-text:           #f8f3e8;
    --color-text-muted:     #bda887;
    --color-border:         #2f4a3a;
    --color-border-soft:    #223b2c;
    --color-primary-light:  #1f3d2b;
    --color-accent-soft:    #3a2a12;
    --color-error-bg:       #3a1a18;
    --color-error:          #eea094;
    --color-success-bg:     #163024;
    --color-success-border: #2f5a40;
    --ink:                  #f3e9d2;
    --ink-soft:             #e4d9c0;
    /* Raw paper roles, remapped the way the app's darkPaper does (colors.ts), so pages that
       use the brown and cream tokens directly stay readable when the attribute is forced. Green
       and amber fills are not remapped: buttons keep their day colours. (C2: the old wording held
       a stray asterisk-slash that closed this comment early and dropped --cream-50.) */
    --cream-50:  #1a3425;
    --cream-100: #0e2015;
    --cream-200: #284433;
    --cream-300: #3a5945;
    --brown-900: #f8f3e8;
    --brown-700: #e4dac7;
    --brown-500: #bda887;
    --brown-300: #8c7c63;
    --green-50:  #1c3827;
    --green-100: #24452f;
    --green-200: #33634a;
    --sun-50:    #36281a;
    --sun-100:   #4a3519;
    --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.28), 0 2px 6px rgba(0, 0, 0, 0.26);
    --shadow-md:    0 2px 4px rgba(0, 0, 0, 0.3), 0 6px 16px rgba(0, 0, 0, 0.32), 0 12px 32px rgba(0, 0, 0, 0.26);
    --shadow-lg:    0 4px 10px rgba(0, 0, 0, 0.32), 0 16px 40px rgba(0, 0, 0, 0.4), 0 30px 80px rgba(0, 0, 0, 0.36);
    --shadow-flat:  0 0 0 1px rgba(0, 0, 0, 0.35);
    --shadow-lift:  0 6px 16px -8px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(0, 0, 0, 0.3);
    --tp-grain-alpha:    0.035;
    --tp-grain-blend:    screen;
    --tp-paper-top:      #1c3827;
    --tp-paper-bottom:   #1a3425;
    --tp-paper-dot:      rgba(58, 89, 69, 0.7);
    --tp-paper-contours: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 140' preserveAspectRatio='none' fill='none' stroke='%233f6a4f' stroke-opacity='.6' stroke-width='1.1' stroke-linecap='round'%3E%3Cpath d='M-11 77C40 67 70 87 110 77S180 65 231 73'/%3E%3Cpath d='M-11 99C40 89 70 109 110 99S180 87 231 95'/%3E%3Cpath d='M-11 121C40 111 70 131 110 121S180 109 231 117'/%3E%3Cellipse cx='172' cy='34' rx='36' ry='18'/%3E%3Cellipse cx='172' cy='34' rx='25' ry='12.6'/%3E%3Cellipse cx='172' cy='34' rx='14.4' ry='7.2'/%3E%3C/svg%3E");
    --tp-tape-fill:      rgba(58, 89, 69, 0.8);
    --tp-stamp-blend:    screen;
    --tp-kraft:          #213a2b;
    --tp-kraft-line:     #345240;
    --tp-mount:          #f3e9d2;
    color-scheme: dark;
}
[data-theme="dark"], [data-theme="dark"] body { background: var(--color-bg); color: var(--color-text); }
[data-theme="dark"] .textured-bg {
    background-image:
        radial-gradient(ellipse 80% 50% at 50% -10%, rgba(140, 199, 161, 0.06), transparent),
        radial-gradient(ellipse 60% 42% at 100% 100%, rgba(242, 168, 84, 0.04), transparent);
}
/* --- Reset --- */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    background: var(--color-bg); /* no white band under short pages */
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

body {
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
    color: var(--color-text);
    background: var(--color-bg);
    min-height: 100vh;
    font-optical-sizing: auto;
}

::selection {
    background: rgba(62, 122, 84, 0.22);
    color: var(--brown-900);
}

img, svg { vertical-align: middle; }

/* Thin, warm scrollbars — the browser chrome is part of the design too */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--cream-300) transparent;
}
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb {
    background: var(--cream-300);
    border-radius: 99px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--brown-300); }
*::-webkit-scrollbar-track { background: transparent; }

/* Subtle topographic-grain texture for the rugged, outdoorsy feel.
   Applied per-page via the .textured-bg class on <body>. */
.textured-bg {
    background-color: var(--color-bg);
    background-image:
        radial-gradient(ellipse 80% 50% at 50% -10%, rgba(62, 122, 84, 0.07), transparent),
        radial-gradient(ellipse 60% 42% at 100% 100%, rgba(224, 134, 47, 0.035), transparent),
        repeating-radial-gradient(
            circle at 12% 18%,
            transparent 0,
            transparent 110px,
            rgba(76, 62, 41, 0.024) 110px,
            rgba(76, 62, 41, 0.024) 112px
        ),
        repeating-radial-gradient(
            circle at 88% 82%,
            transparent 0,
            transparent 90px,
            rgba(42, 83, 57, 0.022) 90px,
            rgba(42, 83, 57, 0.022) 92px
        );
    background-attachment: fixed;
}

/* background-attachment: fixed breaks position:fixed descendants (e.g. the
   bottom tab bar) on iOS/Android while scrolling — keep the texture, drop fixed. */
@media (max-width: 900px) {
    .textured-bg {
        background-attachment: scroll;
    }
}

/* --- Typography --- */
h1, h2, h3 {
    font-family: var(--font-display);
    font-weight: 640;
    line-height: 1.18;
    letter-spacing: -0.014em;
    color: var(--brown-900);
    font-variation-settings: 'opsz' 40;
}

a {
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
}
a:hover { text-decoration: underline; }

/* Numbers that count (stats, XP, prices) should never jiggle */
.tabular-nums { font-variant-numeric: tabular-nums; }

/* --- Focus — visible, warm, never a default blue outline ---
   A real outline (survives component box-shadows and forced-colors mode) in a burnt amber
   that reads on both warm paper (~3.9:1) and deep forest (~4.8:1). Text fields keep their
   soft ring; the transparent outline still shows in Windows high-contrast. */
:root { --color-focus: #c46a17; }

:focus-visible {
    outline: 2.5px solid var(--color-focus);
    outline-offset: 2px;
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 2px solid transparent;
    outline-offset: 0;
    box-shadow: var(--ring-primary);
}

/* --- Shared form field --- */
.field {
    margin-bottom: 20px;
}

.field label {
    display: block;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--brown-700);
    margin-bottom: 7px;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="password"] {
    width: 100%;
    padding: 12px 15px;
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--color-text);
    background: var(--color-surface);
    outline: none;
    box-shadow: inset 0 1px 2px rgba(38, 32, 15, 0.03);
    transition: border-color var(--duration-fast) ease,
        box-shadow var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-out);
}

.field input::placeholder { color: var(--brown-300); }

.field input:focus {
    border-color: var(--color-border-focus);
    box-shadow: var(--ring-primary), 0 2px 10px rgba(62, 122, 84, 0.08);
}

/* Mobile browsers (notably iOS Safari) auto-zoom toward a focused form
   control whose font-size is below 16px — which happens when a modal with an
   input opens — and then leave the page stuck zoomed in. Guaranteeing a 16px
   minimum on small viewports stops the zoom entirely while still letting users
   pinch-to-zoom on their own. !important is needed to win over the more
   specific input rules elsewhere. */
@media (max-width: 768px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea {
        font-size: 16px !important;
    }
}

/* --- Buttons --- */
.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 22px;
    border: none;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.005em;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background var(--duration-fast) ease,
        box-shadow var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-spring),
        color var(--duration-fast) ease,
        border-color var(--duration-fast) ease,
        filter var(--duration-fast) ease;
    text-decoration: none;
}

.btn:hover { text-decoration: none; }

.btn:active { transform: translateY(1px) scale(0.97); transition-duration: 0.06s; }

.btn-primary {
    background: linear-gradient(180deg, var(--green-600) 0%, var(--green-700) 55%, #38724d 100%);
    color: #fff;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22),
        0 1px 2px rgba(26, 52, 37, 0.28),
        0 4px 12px rgba(42, 83, 57, 0.24);
}
.btn-primary:hover {
    color: #fff;
    filter: brightness(1.06) saturate(1.05);
    transform: translateY(-1px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), var(--shadow-primary);
}
.btn-primary:active { transform: translateY(1px) scale(0.97); filter: brightness(0.98); }
.btn-primary:disabled {
    background: var(--brown-300);
    cursor: not-allowed;
    transform: none;
    filter: none;
    box-shadow: none;
}

.btn-ghost {
    background: transparent;
    color: var(--color-text-muted);
    border: 1.5px solid var(--color-border);
}
.btn-ghost:hover {
    background: var(--cream-200);
    border-color: var(--brown-300);
    color: var(--color-text);
}
.btn-ghost:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-full { width: 100%; }

/* --- Feedback messages --- */
.msg-error {
    background: var(--color-error-bg);
    color: var(--color-error);
    border: 1px solid #efc4bf;
    border-radius: var(--radius-sm);
    padding: 9px 13px;
    font-size: 0.875rem;
    margin-bottom: 16px;
    display: none;
}
.msg-error.visible { display: block; animation: shake-no 0.4s var(--ease-out); }

.msg-success {
    background: var(--color-success-bg);
    color: var(--color-success);
    border: 1px solid var(--color-success-border);
    border-radius: var(--radius-sm);
    padding: 9px 13px;
    font-size: 0.875rem;
    margin-bottom: 16px;
    display: none;
}
.msg-success.visible { display: block; animation: rise-in 0.35s var(--ease-out); }

/* ============================================================
   Skeletons — perceived speed. Use instead of spinners.
   ============================================================ */
.skeleton {
    position: relative;
    overflow: hidden;
    background: linear-gradient(180deg, var(--cream-200), #e9e0cc);
    border-radius: var(--radius-sm);
    color: transparent !important;
    user-select: none;
    pointer-events: none;
}
.skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg,
        transparent 20%,
        rgba(254, 252, 247, 0.75) 50%,
        transparent 80%);
    transform: translateX(-100%);
    animation: skeleton-sweep 1.4s var(--ease-swift) infinite;
}
.skeleton--text  { height: 0.9em; border-radius: 6px; }
.skeleton--title { height: 1.3em; border-radius: 8px; }
.skeleton--circle { border-radius: 50%; }

@keyframes skeleton-sweep {
    to { transform: translateX(100%); }
}

/* ============================================================
   Toasts — created by ui-fx.js (TPFX.toast)
   ============================================================ */
.tpfx-toast-stack {
    position: fixed;
    left: 50%;
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    gap: 8px;
    z-index: 4000;
    pointer-events: none;
}

@media (max-width: 900px) {
    /* Sit above the floating mobile tab bar */
    .tpfx-toast-stack { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
}

.tpfx-toast {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    max-width: min(420px, calc(100vw - 32px));
    padding: 11px 18px 11px 14px;
    border-radius: 999px;
    background: rgba(26, 52, 37, 0.96);
    border: 1px solid rgba(254, 252, 247, 0.14);
    color: var(--cream-50);
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.35;
    box-shadow: 0 6px 24px rgba(14, 32, 21, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.08);
    pointer-events: auto;
    cursor: pointer;
    animation: toast-in var(--duration-slow) var(--ease-spring-soft);
}

.tpfx-toast.is-leaving {
    animation: toast-out var(--duration-base) var(--ease-swift) forwards;
}

.tpfx-toast-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background: rgba(140, 199, 161, 0.22);
    color: var(--green-300);
}

.tpfx-toast--success .tpfx-toast-icon { background: rgba(140, 199, 161, 0.25); color: var(--green-300); }
.tpfx-toast--accent  .tpfx-toast-icon { background: rgba(242, 168, 84, 0.25); color: var(--sun-400); }
.tpfx-toast--error {
    background: rgba(90, 30, 26, 0.95);
}
.tpfx-toast--error .tpfx-toast-icon { background: rgba(255, 173, 163, 0.22); color: #ffb3a9; }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(16px) scale(0.92); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toast-out {
    to { opacity: 0; transform: translateY(10px) scale(0.94); }
}

/* ============================================================
   Scroll reveals — gated on html.tpfx so content is never
   hidden if JS fails. ui-fx.js adds the class + observes.
   ============================================================ */
html.tpfx [data-reveal] {
    opacity: 0;
    transform: translateY(18px);
}
html.tpfx [data-reveal].is-revealed {
    opacity: 1;
    transform: translateY(0);
    transition: opacity var(--duration-slower) var(--ease-out),
        transform var(--duration-slower) var(--ease-out);
    transition-delay: var(--reveal-delay, 0s);
}

/* ============================================================
   Shared animations
   ============================================================ */
@keyframes rise-in {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes scale-in {
    from { opacity: 0; transform: scale(0.96) translateY(8px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* Springy entrance for things that should feel alive (badges, chips, pins) */
@keyframes pop-in {
    0%   { opacity: 0; transform: scale(0.5); }
    70%  { opacity: 1; transform: scale(1.06); }
    100% { opacity: 1; transform: scale(1); }
}

/* Reward pulse — hearts, saves, check-ins */
@keyframes heart-pop {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.35); }
    60%  { transform: scale(0.92); }
    100% { transform: scale(1); }
}

/* Gentle error shake — "no" without shouting */
@keyframes shake-no {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    50% { transform: translateX(4px); }
    75% { transform: translateX(-2px); }
}

/* Soft attention pulse for glowing CTAs */
@keyframes glow-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(62, 122, 84, 0.35); }
    55%      { box-shadow: 0 0 0 9px rgba(62, 122, 84, 0); }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Screen-reader-only text (announcements, extra labels) */
.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --- "Send to…" dialog (tp-send-to.js) --- */
.tp-send-to {
    width: min(440px, calc(100vw - 32px));
    max-height: min(84vh, 680px);
    display: flex;
    flex-direction: column;
}

.tp-send-to-label {
    display: block;
    margin: 12px 0 6px;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--color-text);
}

.tp-send-to-label[hidden],
.tp-send-to-note[hidden] {
    display: none;
}

.tp-send-to-note,
.tp-send-to-search {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1.5px solid var(--color-border-soft);
    border-radius: var(--radius-md);
    background: var(--cream-50);
    font: inherit;
    font-size: 0.92rem;
    resize: none;
}

.tp-send-to-note:focus,
.tp-send-to-search:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(62, 122, 84, 0.14);
}

.tp-send-to-list {
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
    overflow-y: auto;
    min-height: 120px;
}

.tp-send-to-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 4px;
    border-bottom: 1px solid var(--color-border-soft);
}

.tp-send-to-row:last-child {
    border-bottom: none;
}

.tp-send-to-avatar {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--green-100);
    color: var(--color-primary-dark);
    font-size: 0.78rem;
    font-weight: 800;
}

.tp-send-to-who {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.tp-send-to-who strong {
    font-size: 0.92rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tp-send-to-who span {
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

.tp-send-to-btn {
    flex-shrink: 0;
    padding: 7px 14px;
    font-size: 0.82rem;
}

.tp-send-to-empty {
    padding: 18px 4px;
    color: var(--color-text-muted);
    font-size: 0.9rem;
    text-align: center;
}

/* The hidden attribute always wins over component display rules (buttons, flex rows…). */
[hidden] {
    display: none !important;
}


/* ============================================================
   SHARED MODAL SYSTEM
   Contract (do not break): .modal-overlay.open { display:flex },
   .modal, .modal-close, .modal-sub, .modal-actions,
   .modal--confirm, .modal--list. Used by home.html (Convoy),
   the global Plan-a-Drive modal, and every page in the shell.
   ============================================================ */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(14, 32, 21, 0.52);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.modal-overlay.open {
    display: flex;
    animation: fade-in 0.22s ease both;
}

.modal {
    background: var(--color-surface);
    border: 1px solid var(--color-border-soft);
    border-radius: var(--radius-xl);
    padding: 36px 36px 32px;
    width: 100%;
    max-width: 480px;
    box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.7);
    position: relative;
}

/* Springy entrance — confirmation should feel alive, not clinical */
.modal-overlay.open .modal {
    animation: modal-pop-in 0.42s var(--ease-spring-soft) both;
}

@keyframes modal-pop-in {
    from { opacity: 0; transform: translateY(22px) scale(0.93); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 1px solid transparent;
    border-radius: 50%;
    background: transparent;
    font-size: 1.4rem;
    color: var(--brown-300);
    cursor: pointer;
    line-height: 1;
    z-index: 2;
    transition: color var(--duration-fast) ease,
        background var(--duration-fast) ease,
        border-color var(--duration-fast) ease,
        transform var(--duration-base) var(--ease-spring);
}
.modal-close:hover {
    color: var(--brown-700);
    background: var(--cream-200);
    border-color: var(--cream-300);
    transform: rotate(90deg);
}
.modal-close:active { transform: rotate(90deg) scale(0.9); }

.modal h2 {
    font-family: var(--font-display);
    font-size: 1.34rem;
    font-weight: 680;
    margin-bottom: 5px;
    color: var(--brown-900);
    padding-right: 30px;
}

.modal-sub {
    color: var(--color-text-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    margin-bottom: 26px;
}

.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 8px;
}

[data-theme="dark"] .modal { box-shadow: var(--shadow-lg); }
@media (max-width: 480px) {
    .modal { padding: 30px 20px 22px; border-radius: var(--radius-lg); }
    .modal-actions { flex-wrap: wrap; }
}

/* Confirm dialogs: tighter, decisive */
.modal--confirm {
    max-width: 440px;
}

.modal--confirm .modal-sub {
    margin-bottom: 22px;
}

.btn-danger {
    background: linear-gradient(180deg, #c2493c 0%, #a93327 100%);
    color: #fff;
    border: none;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18),
        0 2px 8px rgba(147, 49, 45, 0.28);
}

.btn-danger:hover {
    filter: brightness(1.07);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18),
        0 4px 14px rgba(147, 49, 45, 0.34);
}

.btn-danger:active { transform: translateY(1px) scale(0.97); }

.btn-danger:disabled {
    background: #e0a49d;
    cursor: not-allowed;
    transform: none;
    filter: none;
    box-shadow: none;
}

/* --- Legacy modal form submit button --- */
.modal .submit-btn {
    width: 100%;
    background: var(--color-primary);
    color: #fff;
    border: none;
    padding: 13px;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    margin-top: 8px;
    transition: background var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.modal .submit-btn:hover { background: var(--color-primary-dark); }
.modal .submit-btn:active { transform: translateY(1px) scale(0.98); }
.modal .submit-btn:disabled {
    background: var(--brown-300);
    cursor: not-allowed;
    transform: none;
}

/* Feedback inside legacy modals */
#form-error {
    color: var(--color-error);
    background: var(--color-error-bg);
    border: 1px solid #f0c0c0;
    border-radius: var(--radius-sm);
    padding: 9px 13px;
    font-size: 0.875rem;
    margin-top: 12px;
    display: none;
}

#form-success {
    color: var(--color-success);
    font-size: 0.875rem;
    font-weight: 600;
    margin-top: 12px;
    display: none;
}

/* --- Autocomplete dropdown --- */
.ac-wrapper { position: relative; }

.ac-dropdown {
    position: absolute;
    top: calc(100% + 5px);
    left: 0;
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border-soft);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    z-index: 200;
    overflow: hidden;
    display: none;
    padding: 4px;
}
.ac-dropdown.open {
    display: block;
    animation: ac-drop-in 0.18s var(--ease-out) both;
}

@keyframes ac-drop-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.ac-item {
    padding: 9px 11px;
    font-size: 0.9rem;
    color: var(--color-text);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-radius: var(--radius-sm);
    transition: background 0.12s, color 0.12s;
}
.ac-item:hover,
.ac-item.highlighted {
    background: var(--green-50);
    color: var(--color-primary-dark);
}

.ac-item--muted {
    color: var(--color-text-muted);
    cursor: default;
    font-size: 0.85rem;
}

.ac-item--muted:hover {
    background: transparent;
    color: var(--color-text-muted);
}

@media (max-width: 600px) {
    .modal { padding: 32px 22px 26px; border-radius: 22px; }
}

/* --- Custom date trigger button --- */
.date-trigger {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 11px 14px;
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text);
    background: var(--color-surface);
    cursor: pointer;
    text-align: left;
    transition: border-color var(--duration-fast) ease,
        box-shadow var(--duration-fast) ease,
        background var(--duration-fast) ease;
}
.date-trigger svg { color: var(--color-primary); flex-shrink: 0; }
.date-trigger:hover { border-color: var(--green-300); box-shadow: var(--shadow-xs); }
.date-trigger.is-open {
    border-color: var(--color-border-focus);
    box-shadow: var(--ring-primary);
}
.date-trigger.is-empty .date-trigger-label { color: var(--brown-300); font-weight: 500; }
.date-trigger-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- Floating popover (calendar + menus) --- */
.tp-pop {
    position: fixed;
    z-index: 300;
    display: none;
    opacity: 0;
    transform: translateY(-6px) scale(0.96);
    transform-origin: top left;
    transition: opacity 0.16s ease, transform 0.24s var(--ease-spring-soft);
}
.tp-pop.open { display: block; }
.tp-pop.shown { opacity: 1; transform: translateY(0) scale(1); }

/* --- Calendar: satisfying date picking --- */
.cal {
    width: 278px;
    padding: 13px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-soft);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.cal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}
.cal-title {
    font-family: var(--font-display);
    font-weight: 660;
    font-size: 1rem;
    color: var(--brown-900);
}
.cal-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px; height: 30px;
    border: 1px solid var(--color-border);
    border-radius: 9px;
    background: var(--cream-50);
    color: var(--brown-700);
    cursor: pointer;
    transition: background var(--duration-fast) ease,
        color var(--duration-fast) ease,
        border-color var(--duration-fast) ease,
        transform var(--duration-base) var(--ease-spring);
}
.cal-nav:hover { background: var(--green-50); color: var(--color-primary); border-color: var(--green-200); }
.cal-nav:active { transform: scale(0.88); }
.cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.cal-weekdays {
    margin-bottom: 4px;
}
.cal-weekdays span {
    text-align: center;
    font-size: 0.66rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--brown-300);
    padding: 4px 0;
}
.cal-day {
    aspect-ratio: 1 / 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 9px;
    background: transparent;
    color: var(--brown-900);
    font-family: var(--font-body);
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--duration-fast) ease,
        color var(--duration-fast) ease,
        transform var(--duration-base) var(--ease-spring),
        box-shadow var(--duration-fast) ease;
}
.cal-day:hover:not(:disabled):not(.is-selected) {
    background: var(--green-50);
    color: var(--color-primary-dark);
    transform: scale(1.12);
}
.cal-day:active:not(:disabled) { transform: scale(0.9); }
.cal-day.is-muted { color: var(--brown-300); opacity: 0.5; }
.cal-day.is-today { box-shadow: inset 0 0 0 1.5px var(--green-200); }
.cal-day.is-selected {
    background: var(--color-primary);
    color: #fff;
    box-shadow: var(--shadow-primary);
    animation: pop-in 0.32s var(--ease-spring-soft);
}
.cal-day.is-selected:hover { background: var(--color-primary-dark); color: #fff; }
.cal-day:disabled { color: var(--brown-300); opacity: 0.3; cursor: not-allowed; }
.cal-foot {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--color-border-soft);
}
.cal-foot-btn {
    flex: 1;
    padding: 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--cream-50);
    color: var(--brown-700);
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
    transition: background var(--duration-fast) ease,
        color var(--duration-fast) ease,
        border-color var(--duration-fast) ease,
        transform var(--duration-base) var(--ease-spring);
}
.cal-foot-btn:hover { background: var(--green-50); color: var(--color-primary); border-color: var(--green-200); }
.cal-foot-btn:active { transform: scale(0.96); }
.cal-foot-btn--clear:hover { background: #fdf1ef; color: var(--color-error); border-color: #efc4bf; }

/* ---------- Share modal (Prompt 5, js/tp-share.js) ---------- */
.tp-share { max-width: 460px; }
.tp-share-label { display: block; font-size: 0.82rem; font-weight: 700; color: var(--color-text-muted); margin: 14px 0 6px; }
.tp-share-url-row { display: flex; gap: 8px; }
.tp-share-url {
    flex: 1; min-width: 0; padding: 10px 12px; border-radius: var(--radius-md);
    border: 1.5px solid var(--color-border); background: var(--color-surface); color: var(--color-text);
    font: inherit; font-size: 0.9rem;
}
.tp-share-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.tp-share-card-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
.tp-share-card {
    display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 12px; min-width: 0;
    border-radius: var(--radius-lg); border: 1.5px solid var(--color-border-soft); background: var(--color-surface);
    color: var(--color-text); text-decoration: none; font-weight: 700; font-size: 0.9rem;
    transition: border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.tp-share-card small { font-weight: 500; color: var(--color-text-muted); font-size: 0.78rem; }
.tp-share-card:hover { border-color: var(--color-primary); transform: translateY(-1px); }
.tp-share-thumb {
    display: block; width: 100%; border-radius: var(--radius-sm); background: var(--cream-200) center / cover no-repeat;
    margin-bottom: 6px;
}
.tp-share-thumb--story { aspect-ratio: 9 / 16; height: 150px; width: auto; }
.tp-share-thumb--square { aspect-ratio: 1 / 1; width: 100%; max-width: 150px; height: auto; margin-top: auto; margin-bottom: auto; }
@media (prefers-reduced-motion: reduce) { .tp-share-card { transition: none; } .tp-share-card:hover { transform: none; } }

/* ---------- Search-indexing notice (Prompt 5) ---------- */
.tp-notice {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
    margin: 12px 16px; padding: 14px 16px; border-radius: var(--radius-lg);
    background: var(--green-50); border: 1.5px solid var(--green-200); color: var(--color-text);
}
.tp-notice p { margin: 0; flex: 1 1 260px; font-size: 0.95rem; }
.tp-notice-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.tp-notice .btn { padding: 8px 14px; }
.tp-notice--floating {
    position: fixed; z-index: 60; left: 16px; right: 16px; bottom: calc(84px + env(safe-area-inset-bottom, 0px));
    margin: 0; box-shadow: var(--shadow-lg); max-width: 640px;
}
@media (min-width: 901px) {
    .tp-notice--floating { left: auto; right: 24px; bottom: 24px; }
}

/* ============================================================
   Driven stamp (Prompt 10). Amber is reserved for reward, and a drive you
   actually drove is one. Used on the drive view hero, Plans cards and trip day rows.
   ============================================================ */
.driven-stamp {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-family: var(--font-body);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sun-600);
    background: var(--sun-100);
    border: 1px solid rgba(242, 168, 84, 0.5);
    white-space: nowrap;
    vertical-align: middle;
}
.driven-stamp::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--sun-500);
    box-shadow: 0 0 0 2px var(--sun-50);
}
/* On the deep-forest trip cards the stamp reads as an amber ring, like the countdown chip. */
.trip-card .driven-stamp,
.dv-hero .driven-stamp {
    color: var(--sun-400);
    background: rgba(242, 168, 84, 0.14);
    border-color: rgba(242, 168, 84, 0.4);
}
.dv-hero .driven-stamp::before { box-shadow: none; }

/* ---------- Creator badge (Prompt 14) ----------
   Set by an admin; shown next to the Pro badge wherever author names appear. Deep forest on cream
   (Pro is teal, Picks are warm editorial, amber stays reserved for rewards). Markup:
   <span class="creator-badge"><svg …/>Creator</span> (js: TPCreatorBadge.html() / .node()). */
.creator-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px 2px 6px;
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    line-height: 1.5;
    text-transform: uppercase;
    color: var(--green-50);
    background: var(--green-850);
    border: 1px solid var(--green-950);
    white-space: nowrap;
    vertical-align: middle;
}
.creator-badge svg { width: 11px; height: 11px; flex: none; color: var(--green-200); }
.creator-badge[hidden] { display: none !important; }


/* ============================================================
   C1 textures (docs/cozy-style.md). Each has a night-forest value through the tokens above,
   switches off under Reduce Transparency, and nothing here ever moves.
   ============================================================ */

/* Paper grain: one 96px tile at alpha <= .04. Page backgrounds and large cards only. */
.tp-paper { position: relative; }
.tp-paper::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--tp-grain-url) repeat 0 0 / 96px 96px;
    opacity: var(--tp-grain-alpha);
    mix-blend-mode: var(--tp-grain-blend);
    pointer-events: none;
    z-index: 0;
}
/* On a page body the grain is a fixed sheet over everything (no blend, so scrolling stays cheap). */
body.tp-paper::after { position: fixed; z-index: 0; mix-blend-mode: normal; opacity: calc(var(--tp-grain-alpha) * 0.8); }

/* Fold-out road map paper: the CSS twin of RoutePreviewService.paperBackground
   (gradient, 22px dot grid, three ridges and a hill). Put it on every route-sketch slot. */
.tp-paper-map {
    background:
        var(--tp-paper-contours) center / 100% 100% no-repeat,
        radial-gradient(circle at 1px 1px, var(--tp-paper-dot) 1px, transparent 1.6px) 0 0 / 22px 22px,
        linear-gradient(180deg, var(--tp-paper-top), var(--tp-paper-bottom));
}

/* Masking tape: a torn strip across a corner or the top edge. --tape-angle sets the tilt (static). */
.tp-tape { position: relative; }
.tp-tape::before {
    content: '';
    position: absolute;
    z-index: 2;
    width: 84px;
    height: 22px;
    top: -9px;
    left: 50%;
    background: var(--tp-tape-fill);
    transform: translateX(-50%) rotate(var(--tape-angle, -2deg));
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 22' preserveAspectRatio='none'%3E%3Cpath d='M1.5 3 3 .5 7 2l5-1.5 4 1.6 4-1.2 61 2.2 1.2 2.4-.6 3 1 3.2-.8 4.6.5 3.3-1.4 1.6-66 1.3-3.4-1.4-3.6 1.1-4.3-.8L2 20.4l-1.5-2.2.7-3.3-.8-3.6 1-3.5-.6-2.6z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 22' preserveAspectRatio='none'%3E%3Cpath d='M1.5 3 3 .5 7 2l5-1.5 4 1.6 4-1.2 61 2.2 1.2 2.4-.6 3 1 3.2-.8 4.6.5 3.3-1.4 1.6-66 1.3-3.4-1.4-3.6 1.1-4.3-.8L2 20.4l-1.5-2.2.7-3.3-.8-3.6 1-3.5-.6-2.6z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    pointer-events: none;
}
.tp-tape--left::before  { left: 14px; transform: translateX(-40%) rotate(var(--tape-angle, -34deg)); top: 2px; }
.tp-tape--right::before { left: auto; right: 14px; transform: translateX(40%) rotate(var(--tape-angle, 34deg)); top: 2px; }
.tp-tape--top::before   { left: 50%; top: -10px; }

/* Deckle edge: a torn paper edge along the top or bottom, done with a mask so the surface colour stays. */
.tp-deckle--top {
    -webkit-mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath d='M0 8V5.2C1.4 3.4 2.6 1 4 2.2 5.6 3.6 6.4 0 8 1.4 9.5 2.7 10.4 3.8 12 2c.8-.9 1.4.6 2 1.3V8z'/%3E%3C/svg%3E") top / 14px 8px repeat-x,
        linear-gradient(#000, #000) 0 8px / 100% calc(100% - 8px) no-repeat;
    mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath d='M0 8V5.2C1.4 3.4 2.6 1 4 2.2 5.6 3.6 6.4 0 8 1.4 9.5 2.7 10.4 3.8 12 2c.8-.9 1.4.6 2 1.3V8z'/%3E%3C/svg%3E") top / 14px 8px repeat-x,
        linear-gradient(#000, #000) 0 8px / 100% calc(100% - 8px) no-repeat;
}
.tp-deckle--bottom {
    -webkit-mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath d='M0 0v2.8C1.4 4.6 2.6 7 4 5.8 5.6 4.4 6.4 8 8 6.6c1.5-1.3 2.4-2.4 4-.6.8.9 1.4-.6 2-1.3V0z'/%3E%3C/svg%3E") bottom / 14px 8px repeat-x,
        linear-gradient(#000, #000) 0 0 / 100% calc(100% - 8px) no-repeat;
    mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'%3E%3Cpath d='M0 0v2.8C1.4 4.6 2.6 7 4 5.8 5.6 4.4 6.4 8 8 6.6c1.5-1.3 2.4-2.4 4-.6.8.9 1.4-.6 2-1.3V0z'/%3E%3C/svg%3E") bottom / 14px 8px repeat-x,
        linear-gradient(#000, #000) 0 0 / 100% calc(100% - 8px) no-repeat;
}

/* Date / place stamp: a rubber stamp with a fixed small tilt and a little ink spread. Not a pill. */
.tp-stamp {
    display: inline-block;
    padding: 4px 8px;
    border: 2px solid currentColor;
    border-radius: var(--radius-sm);
    color: var(--green-ink-900);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 0.78rem;
    line-height: 1.2;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    transform: rotate(var(--stamp-angle, -1.5deg));
    text-shadow: 0 0 0.45px currentColor;
    box-shadow: 0 0 0 0.4px currentColor;
    mix-blend-mode: var(--tp-stamp-blend);
    opacity: 0.92;
}
.tp-stamp--place  { color: var(--green-900); }
.tp-stamp--date   { color: var(--ink); }
.tp-stamp--driven { color: var(--sun-600); }
[data-theme="dark"] .tp-stamp--place { color: var(--green-300); }
[data-theme="dark"] .tp-stamp--driven { color: var(--sun-400); }

/* Reduce Transparency: grain off, tape solid, stamps flat. */
@media (prefers-reduced-transparency: reduce) {
    .tp-paper::after { display: none; }
    .tp-tape::before { background: var(--cream-200); }
    [data-theme="dark"] .tp-tape::before { background: #3a5945; }
    .tp-stamp { mix-blend-mode: normal; opacity: 1; }
}

/* C4: any initials avatar (notifications, messages, send-to, flyovers) becomes the official mark
   for @travelpad. The host class keeps its size; this strips the disc behind the embroidery. */
img.tp-avatar--official { background: none !important; border: 0 !important; padding: 0; object-fit: contain; border-radius: 50%; }
span.tp-avatar--official { background-size: contain !important; background-repeat: no-repeat; background-position: center; background-color: transparent !important; border: 0 !important; }

/* Fit utilities (C1): long names truncate, full name goes in title / aria-label. */
.tp-truncate { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tp-clamp-2 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

/* ============================================================
   C2 fit primitives: the one 44px icon button and the squarer tag.
   ============================================================ */
/* .tp-icon-btn: a 44x44 touch target for ⋯, Someday, Settings and row actions. Ink on nothing;
   --bar is the same button on the forest top bar. */
.tp-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--duration-fast) ease, color var(--duration-fast) ease;
}
.tp-icon-btn svg { width: 22px; height: 22px; flex: none; }
.tp-icon-btn:hover { background: var(--cream-200); color: var(--ink); text-decoration: none; }
.tp-icon-btn:focus-visible { outline: none; box-shadow: var(--ring-primary); }
.tp-icon-btn[aria-expanded="true"] { background: var(--cream-200); }
.tp-icon-btn.is-active { color: var(--green-700); }
[data-theme="dark"] .tp-icon-btn:hover,
[data-theme="dark"] .tp-icon-btn[aria-expanded="true"] { background: rgba(255, 255, 255, 0.07); }
.tp-icon-btn--bar { color: rgba(248, 243, 232, 0.86); }
.tp-icon-btn--bar:hover { background: rgba(238, 248, 242, 0.1); color: #fff; }
.tp-icon-btn--sm { width: 36px; height: 36px; }
.tp-icon-btn--sm svg { width: 20px; height: 20px; }

/* .tp-tag: a squarer label (stamps, "Remixed from", categories). Never a pill. */
.tp-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    min-width: 0;
    padding: 3px 8px;
    border: 1px solid var(--brown-300);
    border-radius: var(--radius-sm);
    background: var(--cream-100);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.3;
    white-space: nowrap;
    vertical-align: middle;
}
.tp-tag svg { width: 14px; height: 14px; flex: none; color: var(--green-700); }
.tp-tag .tp-truncate { display: block; }
.tp-tag--remix { background: var(--cream-50); }
[data-theme="dark"] .tp-tag { background: rgba(255, 255, 255, 0.05); }
@media (max-width: 430px) {
    .tp-tag { font-size: 0.68rem; padding: 2px 6px; gap: 4px; }
    .tp-tag svg { width: 12px; height: 12px; }
}
[data-theme="dark"] .tp-tag svg { color: var(--green-300); }

/* A header row above a card: eyebrow left, 44px icon buttons right (profile toolbar). */
.tp-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 44px;
    margin: 0 0 6px;
}
.tp-toolbar-actions { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.tp-toolbar .convoy-eyebrow { margin: 0; }

/* ============================================================
   C1 overflow menu (static/js/tp-menu.js). One component: an anchored popover on desktop,
   a bottom sheet at <= 600px. Rows are tags, not pills; danger rows sit last after a hairline.
   ============================================================ */
.tp-menu-trigger { cursor: pointer; }
.tp-menu-trigger[aria-expanded="true"] { background: var(--cream-100); color: var(--color-text); }
[data-theme="dark"] .tp-menu-trigger[aria-expanded="true"] { background: rgba(255, 255, 255, 0.06); }
.tp-menu-trigger svg { width: 20px; height: 20px; }

.tp-menu {
    position: fixed;
    z-index: 1200;
    min-width: 220px;
    max-width: min(320px, calc(100vw - 16px));
    padding: 6px;
    border: 1px solid var(--color-border-soft);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    box-shadow: var(--shadow-lift);
    color: var(--color-text);
    font-family: var(--font-body);
    outline: none;
}
.tp-menu.is-measuring { visibility: hidden; }
.tp-menu-title {
    padding: 8px 12px 6px;
    font-family: var(--font-display);
    font-size: 0.95rem;
    font-weight: 640;
    color: var(--ink);
}
.tp-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    padding: 9px 12px;
    border: none;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--color-text);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}
.tp-menu-item:hover,
.tp-menu-item:focus-visible { background: var(--cream-100); outline: none; }
[data-theme="dark"] .tp-menu-item:hover,
[data-theme="dark"] .tp-menu-item:focus-visible { background: rgba(255, 255, 255, 0.06); }
.tp-menu-item[disabled] { opacity: 0.45; cursor: default; }
.tp-menu-item--danger { color: var(--color-error); }
[data-theme="dark"] .tp-menu-item--danger { color: #f0a09a; }
.tp-menu-item.is-armed { background: var(--color-error-bg); }
.tp-menu-item-icon {
    flex: none;
    display: inline-flex;
    width: 20px;
    height: 20px;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
}
.tp-menu-item--danger .tp-menu-item-icon { color: inherit; }
.tp-menu-item-icon svg { width: 20px; height: 20px; }
.tp-menu-item-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tp-menu-item-label { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tp-menu-item-desc { font-size: 0.76rem; font-weight: 500; color: var(--color-text-muted); white-space: normal; }
.tp-menu-check { flex: none; width: 16px; height: 16px; color: var(--color-primary); opacity: 0; }
.tp-menu-check svg { width: 16px; height: 16px; }
.tp-menu-item[aria-checked="true"] .tp-menu-check { opacity: 1; }
.tp-menu-divider { height: 1px; margin: 5px 6px; background: var(--color-border-soft); }

/* Bottom sheet at phone widths */
.tp-menu-scrim {
    position: fixed;
    inset: 0;
    z-index: 1199;
    background: rgba(14, 32, 21, 0.42);
    opacity: 0;
    transition: opacity 0.22s var(--ease-out);
}
.tp-menu-scrim.is-open { opacity: 1; }
.tp-menu--sheet {
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    max-width: none;
    min-width: 0;
    padding: 6px 10px calc(10px + env(safe-area-inset-bottom, 0px));
    border: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: 0 -6px 24px rgba(14, 32, 21, 0.18);
    transform: translateY(100%);
    transition: transform 0.22s var(--ease-out);
}
.tp-menu--sheet.is-open { transform: none; }
.tp-menu--sheet .tp-menu-item { min-height: 52px; font-size: 1rem; padding: 12px 12px; }
.tp-menu--sheet .tp-menu-title { padding-top: 4px; }
.tp-menu-handle {
    width: 36px;
    height: 4px;
    margin: 6px auto 10px;
    border-radius: 2px;
    background: var(--cream-300);
}
[data-theme="dark"] .tp-menu-handle { background: var(--color-border); }
@media (prefers-reduced-motion: reduce) {
    .tp-menu-scrim, .tp-menu--sheet { transition: none; }
}

/* ============================================================
   C5 keepsake kit (docs/cozy-style.md; references: ticket stubs, motel postcards,
   Kodachrome slide mounts, masking tape). Shared by the drive view, post pages, memories,
   recaps and the landing. Decoration sits in reserved margins, never over text or controls,
   and nothing here moves. Helpers that write the markup live in tp-format.js.
   ============================================================ */

/* Ticket stub: perforated ends, dashed tear lines between cells, Courier Prime tabular figures. */
.tp-stub {
    --stub-notch: 7px;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    background: var(--tp-kraft);
    color: var(--ink);
    border-radius: 6px;
    padding: 10px calc(var(--stub-notch) + 8px);
    -webkit-mask:
        radial-gradient(circle var(--stub-notch) at 0 50%, transparent 97%, #000) left / 51% 100% no-repeat,
        radial-gradient(circle var(--stub-notch) at 100% 50%, transparent 97%, #000) right / 51% 100% no-repeat;
    mask:
        radial-gradient(circle var(--stub-notch) at 0 50%, transparent 97%, #000) left / 51% 100% no-repeat,
        radial-gradient(circle var(--stub-notch) at 100% 50%, transparent 97%, #000) right / 51% 100% no-repeat;
    max-width: 100%;
}
.tp-stub-cell {
    /* Cells keep their full value and wrap to a second row on narrow phones rather than clip "12:26" to "12:…". */
    flex: 1 0 auto;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 2px 10px;
    border-left: 1.5px dashed var(--tp-kraft-line);
}
.tp-stub-cell:first-child { border-left: 0; padding-left: 2px; }
.tp-stub-value {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.12rem;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 12ch;
}
.tp-stub-label {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    white-space: nowrap;
}
.tp-stub--compact { padding-top: 7px; padding-bottom: 7px; }
.tp-stub--compact .tp-stub-value { font-size: 0.98rem; }
@media (max-width: 360px) {
    .tp-stub { padding-left: calc(var(--stub-notch) + 4px); padding-right: calc(var(--stub-notch) + 4px); }
    .tp-stub-cell { padding: 2px 7px; }
    .tp-stub-value { font-size: 1rem; }
}

/* Postcard back: message on the left, stamp box and postmark on the right, a centre rule.
   Under 480px the stamp side becomes a row above the message. */
.tp-postcard {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0 18px;
    margin: 0;
    padding: 16px 18px 18px;
    background: var(--tp-mount);
    color: #2c2110;
    border-radius: 4px;
    box-shadow: var(--shadow-flat);
}
.tp-postcard-msg {
    min-width: 0;
    padding-right: 18px;
    border-right: 1.5px solid rgba(44, 33, 16, 0.18);
    font-family: var(--font-display);
    font-style: italic;
    font-size: 1.04rem;
    line-height: 1.55;
    overflow-wrap: anywhere;
}
.tp-postcard-msg p + p { margin-top: 0.6em; }
.tp-postcard-sign { font-style: italic; color: #4c3e29; }
.tp-postcard-side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 12px;
    min-width: 92px;
}
.tp-postcard-stampbox { display: block; width: 46px; height: 56px; }
.tp-postcard-stampbox svg { display: block; width: 100%; height: 100%; }
.tp-postcard-postmark { --stamp-angle: -2deg; color: #1a3425; max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
.tp-postcard-lines {
    display: block;
    width: 100%;
    min-width: 92px;
    height: 34px;
    background: repeating-linear-gradient(180deg, transparent 0 10px, rgba(44, 33, 16, 0.16) 10px 11.5px);
}
@media (max-width: 479px) {
    .tp-postcard { grid-template-columns: 1fr; }
    .tp-postcard-side {
        order: -1;
        flex-direction: row-reverse;
        align-items: center;
        justify-content: space-between;
        padding-bottom: 12px;
        margin-bottom: 12px;
        border-bottom: 1.5px solid rgba(44, 33, 16, 0.18);
    }
    .tp-postcard-lines { display: none; }
    .tp-postcard-msg { padding-right: 0; border-right: 0; }
}

/* Slide mount: the cream Kodachrome card with a dark window and a lip caption (from C4's .of-slide-*). */
.tp-slide {
    display: block;
    margin: 0;
    background: var(--tp-mount);
    border-radius: 3px;
    padding: 10px 10px 8px;
    box-shadow: var(--shadow-lift);
    transform: rotate(var(--tilt, 0deg));
    color: #2c2110;
}
.tp-slide-window {
    display: block;
    aspect-ratio: 3 / 2;
    background: #2c2110;
    border-radius: 2px;
    overflow: hidden;
}
.tp-slide-window img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tp-slide-lip {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 7px 2px 0;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #4c3e29;
    white-space: nowrap;
    overflow: hidden;
}
.tp-slide-lip > span { overflow: hidden; text-overflow: ellipsis; }

/* Taped photo: a white border with a strip of masking tape over the top edge. --tilt is fixed per item. */
.tp-taped {
    display: block;
    margin: 0;
    padding: 6px;
    background: var(--tp-mount);
    border-radius: 2px;
    box-shadow: var(--shadow-lift);
    transform: rotate(var(--tilt, -1deg));
}
.tp-taped img { display: block; width: 100%; height: auto; border-radius: 1px; }
.tp-taped::before { top: -10px; }

/* The drawn postage stamp used in postcard stamp boxes (same 1.8 hand, ink palette). */
.tp-postage { color: #1a3425; }

/* Remix credit as a small rubber stamp: "Remixed from Sam R.'s drive". Sentence case so names read. */
.tp-remix-stamp {
    --stamp-angle: -1deg;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    text-transform: none;
    letter-spacing: 0.02em;
    font-size: 0.76rem;
    color: var(--green-700);
    text-decoration: none;
}
.tp-remix-stamp svg { flex: none; width: 15px; height: 15px; }
.tp-remix-stamp .tp-truncate { min-width: 0; }
a.tp-remix-stamp:hover { text-decoration: underline; }

[data-theme="dark"] .tp-stub { color: var(--ink); }
[data-theme="dark"] .tp-postcard { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4); }
[data-theme="dark"] .tp-remix-stamp { color: var(--green-300); }

/* Sun tint (C5): a background layer under the page, never over text or controls. tp-sun.js sets the colour. */
body.tp-sun::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: var(--tp-sun-tint, transparent);
    transition: background-color 20s linear;
}
[data-theme="dark"] body.tp-sun::before { display: none; }
@media (prefers-reduced-transparency: reduce) {
    body.tp-sun::before { display: none; }
}

/* "On this day" postcard (C5, TPMemory). Cream card stock; the photo taped on at the left
   (on top under 520px); the place-and-date postmark is the second imperfection. */
.tp-memory {
    display: grid;
    grid-template-columns: minmax(120px, 38%) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    padding: 18px 16px 16px 18px;
    background: var(--tp-mount);
    color: #2c2110;
    border-radius: 6px;
    box-shadow: var(--shadow-flat);
}
.tp-memory-media { min-width: 0; padding-top: 6px; }
.tp-memory-media .tp-taped { max-width: 100%; }
.tp-memory-media .tp-taped img { aspect-ratio: 4 / 3; object-fit: cover; }
.tp-memory-route {
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: 3px;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px rgba(44, 33, 16, 0.12);
}
.tp-memory-route img { display: block; width: 100%; height: 100%; object-fit: contain; }
.tp-memory-body { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.tp-memory-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: -6px -8px -4px 0; }
.tp-memory-eyebrow { font-weight: 700; font-size: 0.82rem; color: #3e7a54; }
.tp-memory-more { color: #4c3e29; }
.tp-memory-headline {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.12rem, 1rem + 0.6vw, 1.36rem);
    line-height: 1.28;
    color: #2c2110;
    overflow-wrap: anywhere;
}
.tp-memory-line { font-size: 0.94rem; line-height: 1.45; color: #4c3e29; }
.tp-memory-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 6px; }
.tp-memory-postmark { --stamp-angle: -2deg; color: #1a3425; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.tp-memory-open {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-weight: 700;
    color: #2a5339;
    text-decoration: underline;
    text-underline-offset: 3px;
}
[data-theme="dark"] .tp-memory-open { color: #b5ddc4; }
.tp-memory--large { grid-template-columns: 1fr; padding: 22px; }
.tp-memory--large .tp-memory-media { max-width: 520px; }
.tp-memory--large .tp-memory-headline { font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem); }
@media (max-width: 519px) {
    .tp-memory { grid-template-columns: 1fr; padding: 16px 14px 14px; }
    .tp-memory-media { padding: 6px 4px 0; }
}
/* At night the memory card follows the theme like every other card (the app does the same). */
[data-theme="dark"] .tp-memory { background: var(--color-surface); color: var(--ink); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4); }
[data-theme="dark"] .tp-memory-headline,
[data-theme="dark"] .tp-memory-postmark { color: var(--ink); }
[data-theme="dark"] .tp-memory-line,
[data-theme="dark"] .tp-memory-more { color: var(--ink-soft); }
[data-theme="dark"] .tp-memory-eyebrow { color: #b5ddc4; }

/* "Leave now" departure card (C5, leave-now.js). One primary: Go. */
.ln-modal { max-width: 460px; }
.ln-body { display: flex; flex-direction: column; gap: 12px; padding-right: 28px; }
.ln-title { font-family: var(--font-display); font-weight: 600; font-size: 1.5rem; line-height: 1.2; color: var(--ink); overflow-wrap: anywhere; }
.ln-stub { margin-top: 2px; }
.ln-facts { display: grid; gap: 6px; margin: 0; }
.ln-facts > div { display: flex; gap: 10px; align-items: baseline; }
.ln-facts dt { flex: none; width: 76px; font-size: 0.82rem; font-weight: 700; color: var(--color-text-muted); }
.ln-facts dd { margin: 0; min-width: 0; color: var(--color-text); }
.ln-line { font-family: var(--font-display); font-style: italic; font-size: 1.06rem; line-height: 1.45; color: var(--ink); }
.ln-wait { color: var(--color-text-muted); min-height: 3em; }
.ln-note { font-size: 0.86rem; color: var(--color-text-muted); }
.ln-blocked { padding: 10px 12px; border-radius: var(--radius-sm); background: var(--color-accent-soft); color: var(--color-text); font-size: 0.92rem; }
.ln-actions { flex-wrap: wrap; }
.ln-actions .btn { min-height: 44px; white-space: nowrap; }

/* C5 night forest: light inks that sit on always-dark surfaces keep their day value (the cream and pale-green tokens flip at night). */
[data-theme="dark"] .tpfx-toast { color: #fefcf7; }
[data-theme="dark"] .creator-badge { color: #eef8f2; }
[data-theme="dark"] .creator-badge svg { color: #b5ddc4; }

/* Scrappy (S2, R158): the web side of the app's InkMark / MarginNote / joinMeta. Hand-made marks are
   static, ink only, never on controls or body text, and count toward the three moves a screen may have. */
.tp-margin-note {
    align-self: flex-start;
    display: inline-block;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 500;
    font-size: 0.97rem;
    line-height: 1.35;
    color: var(--ink);
    transform: rotate(var(--tilt, 0deg));
}
.tp-ink-mark { display: block; pointer-events: none; overflow: visible; transform: rotate(var(--tilt, 0deg)); }
.tp-ink-mark path { fill: none; stroke: var(--ink); stroke-opacity: 0.88; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-transparency: reduce) {
    .tp-ink-mark path { stroke-opacity: 1; }
}
/* Metadata as plain text ("38 mi · 1 hr · 4 stops"), not chips. Build it with TPFormat.joinMeta. */
.tp-meta { margin: 0; font-size: 0.9rem; line-height: 1.45; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
/* A plain list row with a hairline, for lists that don't need to be cards. */
.tp-row { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 12px 0; border-bottom: 1px solid var(--color-border-soft); }
.tp-row:last-child { border-bottom: 0; }
