/* The trip page: its shell, the route across the top, the rail of nights.

   The shell changed shape. The assistant used to be a drawer that slid over
   the plan behind a dark scrim, which is a strange thing to do to the feature
   the whole app is built around: to ask it anything you first had to hide the
   thing you were asking about. It is a column now - a peer of the plan, always
   there, scrolling on its own - and it only becomes a drawer on a screen too
   narrow to hold both.

   The trip's name, its dates and its route were also each on screen three
   times: in the topbar, in the header and again in the left rail. Once each. */

.planner-page {
    min-height: 100vh;
    background: var(--canvas);
}

/* ----------------------------------------------------------------- topbar */

.planner-topbar {
    height: var(--topbar-h);
    padding: 0 var(--space-4);
    display: flex;
    align-items: center;
    gap: var(--space-4);
    border-bottom: 1px solid var(--line);
    background: var(--paper);
    position: sticky;
    top: 0;
    z-index: 30;
}
/* The way out, said in words. See the note in routing.js. */
.topbar-back {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 34px;
    padding: 0 var(--space-3) 0 var(--space-2);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--ink-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
}
.topbar-back:hover { background: var(--canvas-2); color: var(--ink); }
.topbar-back svg { flex: none; }

.topbar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}
.saved-state {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--ink-3);
    font-size: var(--text-2xs);
    min-height: 1em;
}
.saved-state:empty { display: none; }
.assistant-button-mark { font-size: var(--text-xs); }

/* ------------------------------------------------------------------ shell */

.planner-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--assistant-w);
    align-items: start;
    min-height: calc(100vh - var(--topbar-h));
}
.planner-main { min-width: 0; }

/* Hidden collapses the column rather than leaving its width behind as a strip
   of empty page - which is what "hide the assistant" should mean, and what
   makes the topbar toggle feel like it did something. */
.planner-body:has(> #assistant-layer[hidden]) { grid-template-columns: minmax(0, 1fr); }

/* The assistant column. Hidden collapses it completely rather than leaving a
   gap, which is what makes the topbar toggle feel like it does something. */
#assistant-layer {
    position: sticky;
    top: var(--topbar-h);
    height: calc(100vh - var(--topbar-h));
    min-width: 0;
    border-left: 1px solid var(--line);
    background: var(--paper);
}

/* ------------------------------------------------------------- trip header */

.trip-head {
    padding: var(--space-5) var(--space-6) var(--space-4);
    border-bottom: 1px solid var(--line);
    background: var(--paper);
}
.trip-head-title { min-width: 0; }
.trip-head h1 {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-hero);
    line-height: var(--leading-tight);
}
#trip-title {
    display: inline-block;
    max-width: 100%;
    padding: 2px var(--space-2);
    margin-left: calc(var(--space-2) * -1);
    border-radius: var(--radius-sm);
    cursor: text;
    transition: background var(--dur-1) var(--ease);
}
#trip-title:hover, #trip-title:focus-visible { background: var(--canvas-2); }

.trip-head-meta {
    margin-top: var(--space-2);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
}
.trip-dates-summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 30px;
    padding: 0 var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-full);
    background: var(--paper);
    color: var(--ink-2);
    transition: border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.trip-dates-summary:hover { border-color: var(--fern); color: var(--fern); }
.trip-dates-summary strong { font-size: var(--text-xs); font-weight: var(--weight-medium); }
.trip-facts {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    color: var(--ink-3);
    font-size: var(--text-xs);
}
.trip-facts:empty { display: none; }

.trip-dates-form {
    margin-top: var(--space-3);
    padding: var(--space-3);
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--canvas);
}
.trip-dates-form[hidden] { display: none; }
.trip-dates-form label { display: grid; gap: var(--space-1); }
.trip-dates-form .field { min-height: 38px; width: 170px; }
.trip-dates-status {
    flex-basis: 100%;
    min-height: 16px;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    color: var(--ink-2);
    font-size: var(--text-xs);
    line-height: var(--leading-normal);
}
.trip-dates-status:empty { display: none; }
/* What a date change did, and the one thing worth doing about it. Outside the
   form, because the form closes on apply and this is the part worth reading.
   The assistant is the only thing that can absorb nine new days sensibly, so
   the sentence carries the button that asks it to. */
.trip-dates-outcome {
    margin: var(--space-3) 0 0;
    padding: var(--space-3);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    border: 1px solid var(--fern-tint-2);
    border-radius: var(--radius-md);
    background: var(--fern-tint);
    color: var(--ink);
    font-size: var(--text-xs);
    line-height: var(--leading-normal);
}
.trip-dates-outcome:empty { display: none; }
.trip-dates-dismiss {
    margin-left: auto;
    width: 26px;
    height: 26px;
    flex: none;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink-3);
    font-size: var(--text-sm);
    line-height: var(--leading-flat);
}
.trip-dates-dismiss:hover { background: var(--fern-tint-2); color: var(--ink); }

.trip-dates-ask {
    min-height: 30px;
    padding: 0 var(--space-3);
    border: 1px solid var(--fern);
    border-radius: var(--radius-full);
    background: var(--paper);
    color: var(--fern);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
}
.trip-dates-ask:hover { background: var(--fern); color: var(--ink-inverse); }

.trip-title-form {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}
.trip-title-form .field {
    flex: 1;
    min-width: 0;
    max-width: 460px;
    font-size: var(--text-md);
    font-weight: var(--weight-semi);
}

/* -------------------------------------------------------------- the route */

.journey-row {
    margin-top: var(--space-4);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}
.journey-row .journey-strip { flex: 1; min-width: 0; }
.edit-route-button { flex: none; }

.journey-strip {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--space-1);
    width: 100%;
    min-width: 0;
}
.journey-node,
.journey-more-wrap {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    flex: 0 0 auto;
}
.journey-chip {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-2);
    flex: 0 0 auto;
    padding: var(--space-1) var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-full);
    background: var(--paper);
    white-space: nowrap;
}
.journey-chip small {
    flex: none;
    color: var(--ink-3);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}
.journey-chip strong {
    min-width: 0;
    color: var(--ink);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.journey-chip.is-start { border-color: var(--fern-tint-2); background: var(--fern-tint); }
.journey-chip.is-start small { color: var(--fern); }
.journey-strip.is-tight .journey-node,
.journey-strip.is-tight .journey-more-wrap,
.journey-strip.is-tight .journey-chip {
    flex: 1 1 0;
    min-width: 0;
    max-width: 100%;
}
.journey-arrow {
    flex: none;
    color: var(--ink-3);
    font-size: var(--text-xs);
    line-height: var(--leading-flat);
}
.journey-more-wrap { position: relative; }
.journey-more {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-full);
    background: var(--canvas);
    color: var(--ink-2);
    font: inherit;
}
.journey-more span { font-size: var(--text-xs); line-height: var(--leading-flat); }
.journey-more small {
    color: var(--ink-3);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    text-transform: uppercase;
}
.journey-more:hover,
.journey-more-wrap.is-open .journey-more {
    border-color: var(--fern);
    background: var(--fern-tint);
    color: var(--fern);
}
.journey-full-route {
    position: absolute;
    top: calc(100% + var(--space-2));
    left: 50%;
    z-index: 40;
    display: grid;
    gap: 2px;
    min-width: 220px;
    max-width: min(320px, 80vw);
    max-height: 280px;
    overflow: auto;
    padding: var(--space-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    box-shadow: var(--shadow-3);
    transform: translateX(-50%);
}
.journey-full-stop {
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr);
    gap: var(--space-2);
    align-items: baseline;
    padding: var(--space-2);
    border-radius: var(--radius-sm);
}
.journey-full-stop small {
    color: var(--ink-3);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}
.journey-full-stop strong {
    min-width: 0;
    color: var(--ink);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    overflow-wrap: anywhere;
}
.journey-full-stop.is-start { background: var(--fern-tint); }
.journey-full-stop.is-start small { color: var(--fern); }

/* --------------------------------------------------------- rail + canvas */

.planner-grid {
    display: grid;
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    align-items: start;
}
.day-rail {
    border-right: 1px solid var(--line);
    padding: var(--space-4) var(--space-3);
    position: sticky;
    top: var(--topbar-h);
    max-height: calc(100vh - var(--topbar-h));
    overflow-y: auto;
    background: var(--canvas);
}
.rail-heading {
    height: 28px;
    padding: 0 var(--space-2);
    display: flex;
    align-items: center;
    color: var(--ink-3);
    font-size: var(--text-2xs);
    letter-spacing: var(--tracking-label);
    font-weight: var(--weight-semi);
    text-transform: uppercase;
}

.day-canvas,
.trip-workspace {
    padding: var(--space-5) clamp(var(--space-4), 2.6vw, var(--space-6)) var(--space-8);
    min-width: 0;
}

.active-day-heading-row {
    display: flex;
    justify-content: space-between;
    align-items: start;
    gap: var(--space-4);
}
.active-day-heading-copy { min-width: 0; }
.day-kicker {
    margin: 0;
    color: var(--fern);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}
.active-day-header h2 {
    margin: var(--space-1) 0 0;
    font-size: var(--text-lg);
    letter-spacing: var(--tracking-tight);
    font-weight: var(--weight-semi);
}
.day-title-row {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}
/* Renaming is a thing you do rarely, so the control waits until the title is
   pointed at rather than sitting beside it permanently. */
.day-title-edit {
    width: 28px;
    height: 28px;
    opacity: 0;
    transition: opacity var(--dur-1) var(--ease);
}
.day-title-row:hover .day-title-edit,
.day-title-edit:focus-visible { opacity: 1; }
.day-title-form {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-2) 0 0;
}
.day-title-form[hidden] { display: none; }
.day-title-form .field { width: min(320px, 100%); min-height: 36px; }

.active-day-meta {
    margin: var(--space-1) 0 0;
    color: var(--ink-3);
    font-size: var(--text-xs);
}
.active-day-meta:empty { display: none; }

.day-stats,
.active-day-stats {
    margin-top: var(--space-3);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.day-stats:empty { display: none; }
.stat-pill,
.day-stat {
    min-height: 28px;
    padding: 0 var(--space-3);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-full);
    background: var(--paper);
    color: var(--ink-2);
    font-size: var(--text-xs);
}

/* Asked for a trip by its address. The server renders the planner rather than
   the home page, so a refresh on /trip/12 does not flash the wrong screen -
   but it cannot render the trip, so the frame arrives and waits. */
.planner-opening {
    display: none;
    padding: var(--space-7) var(--space-6);
    color: var(--ink-3);
    font-size: var(--text-xs);
}
.planner-page.is-opening .planner-opening { display: block; }
.planner-page.is-opening .planner-body { display: none; }

/* --------------------------------------------------------------- the rail */
/* One row per day. It answers "which day is this" and "where am I sleeping",
   and nothing else - see the note at the top of day-rail.js. */

.stop-rail, .stop-rail * { box-sizing: border-box; }
.stop-rail { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.day-list { display: flex; flex-direction: column; gap: var(--space-2); }

.day-row {
    display: grid;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    text-align: left;
    transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
                background var(--dur-1) var(--ease);
}
.day-row:hover { border-color: var(--line-strong); }
.day-row.is-active {
    border-color: var(--fern);
    box-shadow: inset 3px 0 0 var(--fern);
    background: var(--paper);
}
.day-row.is-over { border-color: var(--alert); }

.day-row-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
}
.day-row-top strong {
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-3);
}
.day-row.is-active .day-row-top strong { color: var(--fern); }
.day-row-top span { font-size: var(--text-xs); color: var(--ink-2); }

/* The line the rail exists for. */
.day-row-base {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr);
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}
.day-row-mark {
    width: 34px;
    height: 34px;
    overflow: hidden;
    border-radius: var(--radius-sm);
    background: var(--canvas-2);
}
.day-row-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
.day-row-base-copy { display: flex; flex-direction: column; min-width: 0; }
.day-row-base-copy strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    color: var(--ink);
}
.day-row-base-copy small { color: var(--ink-3); font-size: var(--text-2xs); }
.day-row.has-no-stay .day-row-base-copy strong { color: var(--ink-3); font-weight: var(--weight-normal); }
.day-row.has-no-stay .day-row-mark { border: 1px dashed var(--line-strong); background: transparent; }

.day-row-stats { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.day-row-stat {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--ink-3);
    font-size: var(--text-2xs);
    font-variant-numeric: tabular-nums;
}
.day-row-stat svg { flex: none; }

.day-rail-route {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 38px;
    margin-top: var(--space-1);
    padding: 0 var(--space-3);
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--ink-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}
.day-rail-route:hover { border-color: var(--fern); color: var(--fern); background: var(--fern-tint); }

.stop-rail-empty { margin: 0; color: var(--ink-3); font-size: var(--text-xs); line-height: var(--leading-normal); }
.stop-rail-over {
    margin: 0;
    padding: var(--space-3);
    border: 1px solid var(--alert);
    border-radius: var(--radius-md);
    background: var(--alert-tint);
    color: var(--alert);
    font-size: var(--text-2xs);
    line-height: var(--leading-normal);
}

/* --------------------------------------------------------- template preview */
/* The traveller arrived from a photograph on the home page. "Is this mine
   yet?" should be answered before they read anything else. */

.template-preview-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border-bottom: 1px solid var(--caution);
    background: var(--caution-tint);
}
.template-preview-copy {
    flex: 1;
    min-width: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
}
.template-preview-tag {
    grid-row: span 2;
    align-self: center;
    padding: 2px var(--space-2);
    border-radius: var(--radius-full);
    background: var(--caution);
    color: var(--ink-inverse);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}
.template-preview-copy p { margin: 0; color: var(--ink); font-size: var(--text-xs); }
.template-preview-copy small { color: var(--caution); font-size: var(--text-2xs); }
.template-preview-status { color: var(--caution); font-size: var(--text-2xs); }
.template-preview-keep {
    flex: none;
    min-height: 36px;
    padding: 0 var(--space-4);
    border: 1px solid var(--fern);
    border-radius: var(--radius-md);
    background: var(--fern);
    color: var(--ink-inverse);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
}
.template-preview-keep:hover:not(:disabled) { background: var(--fern-hover); }
.template-preview-keep:disabled { opacity: 0.6; cursor: default; }

/* The same strip once the copy exists. The question has changed from "is this
   saved?" to "yes, and here". */
.template-preview-bar.is-kept {
    border-bottom-color: var(--fern-tint-2);
    background: var(--fern-tint);
}
.template-preview-bar.is-kept .template-preview-tag { background: var(--fern); }
.template-preview-bar.is-kept .template-preview-copy small { color: var(--ink-3); }
.template-preview-dismiss {
    flex: none;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink-3);
    font-size: var(--text-md);
}
.template-preview-dismiss:hover { background: var(--canvas-2); color: var(--ink); }

@media (max-width: 700px) {
    .template-preview-bar { flex-wrap: wrap; padding: var(--space-3) var(--space-4); }
    .template-preview-keep { width: 100%; }
}

/* The day you go home. Its empty bed is not a gap in the plan. */
.day-row.is-last .day-row-base-copy strong { color: var(--ink-2); font-weight: var(--weight-medium); }
.day-row.is-last .day-row-mark { border: 1px dashed var(--line); background: transparent; }

/* ------------------------------------------------------------------ money */
/* See the note at the top of trip-costs.js: a total is the most quotable thing
   on a screen, so it never appears without what it leaves out. */

.trip-costs-summary strong { font-variant-numeric: tabular-nums; }

.costs-panel { width: min(560px, 100%); overflow-y: auto; }
.costs-panel h2 { margin: 0; font-size: var(--text-lg); }
.cost-headline {
    margin: var(--space-2) 0 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-hero);
    font-variant-numeric: tabular-nums;
}
.cost-missing {
    margin: var(--space-2) 0 0;
    color: var(--caution);
    font-size: var(--text-xs);
    line-height: var(--leading-normal);
}

.cost-party { margin: var(--space-4) 0; }
.cost-party-label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--ink-2);
    font-size: var(--text-xs);
}
.cost-party-input {
    width: 64px;
    min-height: 34px;
    padding: 0 var(--space-2);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    background: var(--paper);
    color: var(--ink);
    font: inherit;
    font-size: var(--text-xs);
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.cost-party-input:focus { border-color: var(--fern); outline: 0; box-shadow: 0 0 0 3px var(--fern-tint-2); }
.cost-party-unit { color: var(--ink-3); font-size: var(--text-xs); }

.cost-list { display: grid; gap: var(--space-2); }
.cost-row {
    display: grid;
    grid-template-columns: 148px minmax(0, 1fr) 84px;
    align-items: center;
    gap: var(--space-3);
}
.cost-row-name {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--ink-2);
    font-size: var(--text-xs);
}
.cost-row-name svg { flex: none; color: var(--ink-3); }
.cost-row-bar {
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--canvas-2);
    overflow: hidden;
}
.cost-row-bar span { display: block; height: 100%; background: var(--fern); border-radius: var(--radius-full); }
.cost-row-value {
    text-align: right;
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    font-variant-numeric: tabular-nums;
}

.cost-subheading {
    margin: var(--space-5) 0 var(--space-2);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semi);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-3);
}
.cost-days { display: grid; gap: var(--space-1); }
.cost-day {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: 34px;
    padding: 0 var(--space-3);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--ink-2);
    font-size: var(--text-xs);
    text-align: left;
}
.cost-day:hover { background: var(--canvas); color: var(--ink); }
.cost-day strong { font-variant-numeric: tabular-nums; }

.cost-note {
    margin: var(--space-5) 0 0;
    color: var(--ink-3);
    font-size: var(--text-2xs);
    line-height: var(--leading-normal);
}
.cost-actions { display: flex; justify-content: flex-end; padding-top: var(--space-4); }

/* A day total that is missing pieces says so on its own face. */
.day-stat.is-partial { border-style: dashed; color: var(--ink-3); }

@media (max-width: 560px) {
    .cost-row { grid-template-columns: minmax(0, 1fr) 84px; }
    .cost-row-bar { display: none; }
}

/* Costs partly per person, on a trip that has not counted its travellers. */
.cost-each {
    margin: var(--space-2) 0 0;
    color: var(--ink-2);
    font-size: var(--text-xs);
    line-height: var(--leading-normal);
}
