/* ============================================
   COMPACT CARD LAYOUT - NEW DESIGN
   ============================================
   Compact cards matching the FairlyRemote original design:
   - Info header row with city, time, status inline
   - Horizontal 24h timeline with traffic light coloring
   - Consistent time alignment across stacked cards
   ============================================ */

/* ---- Hide new compact-card by default (only shown in compact mode) ---- */
.compact-card {
    display: none;
}

/* ---- Show compact-card only in compact layout ---- */
body[data-layout="compact"] .compact-card {
    display: flex !important;
    flex-direction: column;
    width: 100%;
}

/* ---- Override: hide old compact display ---- */
body[data-layout="compact"] .compact-time-display {
    display: none !important;
}

/* ---- Override: each section becomes a rounded card ---- */
body[data-layout="compact"] .timezone-section {
    display: flex;
    flex-direction: column;
    padding: 0;
    margin: 0 8px 6px;
    background: var(--surface-primary, var(--bg-primary));
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.06);
    border: 1px solid rgba(0,0,0,0.06);
    /* overflow:VISIBLE (was hidden) so the live now-time badge can overhang
       UPWARD out of the timeline row without being clipped — the badge sits
       above the current cell (translateY(-100%)) and a wider "14:42" string
       centred on a ~13px cell used to get its leading HOURS digits sheared off
       by the card's hidden overflow, leaving only ":42" (user 2026-06-26: "now
       time only shows the minutes not the hours"). The 12px corner-clip that
       overflow:hidden used to provide for the full-bleed coloured cell fills is
       now done locally on .compact-timeline-row (see below), which is the only
       element whose square corners would otherwise poke past the card radius. */
    overflow: visible;
    position: relative;
    min-height: auto;
}

body[data-layout="compact"] .timezone-section:first-child {
    margin-top: 8px;
}

/* ---- Override: container ---- */
body[data-layout="compact"] #timezone-list {
    padding: 0;
}

/* ======== COMPACT CARD HEADER ======== */
body[data-layout="compact"] .compact-card-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    gap: 8px;
    min-height: 0;
}

/* -- Left side: icon + city info -- */
body[data-layout="compact"] .compact-card-left {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

/* Home icon */
body[data-layout="compact"] .compact-home-icon {
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #3b82f6, #14b8a6);
    border-radius: 8px;
    color: white;
    font-size: 11px;
    flex-shrink: 0;
}

/* Reorder padlock in compact mode (2026-07-06, user: "put the padlock back to
   its original location"). padlock.js injects .home-lock-box right after the
   .compact-home-icon so the lock sits beside the home icon in the header — the
   same relationship it has in the detailed card. .compact-card-left is
   overflow:hidden to truncate the city text, so pin the lock box (flex-shrink:0)
   or it would be the thing that gets clipped instead of the text. */
body[data-layout="compact"] .compact-card-left .home-lock-box {
    flex-shrink: 0;
    overflow: visible;
    display: inline-flex;
    align-items: center;
}

/* Offset pill */
body[data-layout="compact"] .compact-offset-pill {
    padding: 2px 6px;
    border-radius: 14px;
    font-size: 10px;
    font-weight: 700;
    flex-shrink: 0;
    line-height: 1.4;
    margin-left: 4px;
}
body[data-layout="compact"] .compact-offset-pill.offset-same { background: rgba(34,197,94,0.15); color: #16a34a; }
body[data-layout="compact"] .compact-offset-pill.offset-close { background: rgba(59,130,246,0.15); color: #2563eb; }
body[data-layout="compact"] .compact-offset-pill.offset-far { background: rgba(239,68,68,0.15); color: #dc2626; }
body[data-layout="compact"] .compact-offset-pill.offset-medium { background: rgba(251,191,36,0.15); color: #d97706; }

/* City info (name + region) */
body[data-layout="compact"] .compact-city-info {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    overflow: hidden;
}

body[data-layout="compact"] .compact-city-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body[data-layout="compact"] .compact-city-name .fa-pencil {
    font-size: 9px;
    opacity: 0;
    transition: opacity 0.15s;
}

body[data-layout="compact"] .compact-city-name:hover .fa-pencil {
    opacity: 0.5;
}

body[data-layout="compact"] .compact-region-date {
    font-size: 10.5px;
    color: var(--text-tertiary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
}

.tz-demo-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    /* Never let the flex city-name-row collapse the SAMPLE chip when the city
       name is long on a narrow phone — it sits in a flex row and would otherwise
       shrink/clip. The chip is tiny; keep it intact. */
    flex-shrink: 0;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    /* SOLID amber chip (2026-07-02, user: "sample pill has bad visibility").
       The old 15%-opacity amber wash with amber-brown text vanished into the
       tinted member-row cards (green/pink) — near-transparent fill + low-
       contrast amber-on-tint. A solid amber fill with white text reads clearly
       on ANY card background and can't be mistaken for the row's own shading.
       White-on-#b45309 ≈ 4.9:1 (passes WCAG AA for this size). */
    color: #ffffff;
    background: #b45309;
    border: 1px solid #92400e;
    border-radius: 4px;
    vertical-align: middle;
    line-height: 1.2;
}

body.dark-mode .tz-demo-badge {
    /* On dark cards keep white text but lift the fill to a brighter amber so
       the chip still pops off the slate row. */
    color: #1f2937;
    background: #fbbf24;
    border-color: #f59e0b;
}

/* UNCONFIRMED (2026-09-04): a row an admin added for someone who has never
   joined. Its name and hours are the admin's guess, so the board says so where
   the claim is made rather than only in the add flow. Deliberately QUIETER than
   SAMPLE — an unconfirmed teammate is a real person, not fake data — so it is
   an outline chip in slate, not a filled warning. Same flex-shrink guard: it
   sits in .city-name-row and would otherwise be clipped by a long city name. */
/* ⭐RESTYLED 2026-09-10 (owner, on a dark Chicago card: "under Chicago roger it
   says unconfirmed ... its the style I don't like. looks like a coding error").
   Exactly right, and the cause is the combination: a TRANSPARENT fill with a
   DASHED border is the web's visual language for a disabled input or an empty
   drop zone, so on a saturated card it read as broken markup rather than as a
   status. The intent above — quieter than SAMPLE, because the person is real —
   was sound; the execution said "unfinished".
   Now a soft filled chip: it belongs to the card, carries its own ground so it
   works on light and dark alike, and a solid hairline instead of a dashed one.
   Sentence case, not shouting caps, for the same reason. */
.tz-unconfirmed-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.2px;
    text-transform: none;
    /* OPAQUE ground (2026-10-12): an 18% slate wash took the row's colour, so
       on a night row (day-cycle dark, body not in dark mode) the slate text sat
       on near-navy and vanished. Same chip, solid hairline, its own ground. */
    color: #334155;
    background: #f1f5f9;
    border: 1px solid rgba(100, 116, 139, 0.45);
    border-radius: 999px;
    vertical-align: middle;
    line-height: 1.35;
}

/* On a dark card the chip needs its own light ground, or the text fights the
   saturated background behind it — which is what made the dashed box read as
   an artefact in the first place. */
body.dark-mode .tz-unconfirmed-badge,
.tz-card--dark .tz-unconfirmed-badge {
    color: #e2e8f0;
    background: rgba(226, 232, 240, 0.16);
    border-color: rgba(226, 232, 240, 0.34);
}

/* STALE (2026-09-05): the same row, still unclaimed a month later. Warmer than
   the fresh state so the eye catches it, but still an outline rather than the
   filled SAMPLE chip — the person is real, only the hours are a stale guess. */
.tz-unconfirmed-badge--stale {
    color: #b45309;
    background: #fef3c7;   /* opaque, as the fresh chip above */
    border-color: rgba(217, 119, 6, 0.45);
}

body.dark-mode .tz-unconfirmed-badge--stale,
.tz-card--dark .tz-unconfirmed-badge--stale {
    color: #fcd34d;
    background: rgba(252, 211, 77, 0.16);
    border-color: rgba(252, 211, 77, 0.36);
}

/* TYPE MARKER (2026-09-11, owner: "make this icon minimal"). The fa-user /
   fa-globe before a row's name had no rule at all, so it inherited the name's
   size and colour and competed with it. It is a marker, not content: smaller,
   muted, and set back. Sized in em so it tracks whatever the name is set to
   rather than pinning a px value that drifts from it. */
.tz-type-icon {
    font-size: 0.78em;
    margin-right: 5px;
    color: #94a3b8;
    opacity: 0.85;
    vertical-align: baseline;
}

body.dark-mode .tz-type-icon,
.tz-card--dark .tz-type-icon {
    color: #94a3b8;
    opacity: 0.75;
}

/* -- Right side: large time + status/hours stacked -- */
body[data-layout="compact"] .compact-card-right {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* Large current time */
body[data-layout="compact"] .compact-big-time {
    font-size: 28px;
    font-weight: 300;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.5px;
    line-height: 1;
}

/* Small column: status badge + working hours stacked */
body[data-layout="compact"] .compact-right-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
}

/* Status badge - reuse existing .availability-status but make compact */
body[data-layout="compact"] .compact-right-meta .availability-status {
    font-size: 9px;
    padding: 1px 7px;
    border-radius: 20px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1.4;
    white-space: nowrap;
}

/* Working hours tiny inline */
body[data-layout="compact"] .compact-wh {
    font-size: 9.5px;
    color: var(--text-tertiary);
    display: flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
    line-height: 1.2;
}
body[data-layout="compact"] .compact-wh i {
    font-size: 8px;
}

/* Compact header clock — 24hr ONLY (user 2026-07-06). The compact card's live
   clock renders through .timezone-right > .timezone-time-info >
   .current-time-large (stacked-timezone-card.js). In compact layout the JS now
   forces 24h and omits the .current-time-ampm span, so the meridiem no longer
   squeezes the digits. Give the bare "HH:MM" a clear, tabular size now that it
   owns the full width — the old 18px was set to leave room for the AM/PM chip
   that no longer exists, so the digits read cramped. Belt-and-suspenders: hide
   any stray meridiem span so a cached 12h render can't reintroduce it here. */
body[data-layout="compact"] .timezone-time-info .current-time-large {
    font-size: 21px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.3px;
    flex-shrink: 0;
    line-height: 1;
}
body[data-layout="compact"] .timezone-time-info .current-time-large .current-time-ampm {
    display: none;
}
body[data-layout="compact"] .timezone-time-info .current-time-digits {
    min-width: 0;
}

/* ======== COMPACT TIMELINE ROW ======== */
body[data-layout="compact"] .compact-timeline-row {
    display: flex;
    flex-direction: row;
    position: relative;
    height: 36px;
    border-top: 1px solid rgba(0,0,0,0.05);
    /* This row is the LAST child of the card and holds the full-bleed coloured
       hour-cell fills (data-traffic). The card itself is now overflow:visible
       (so the now-time badge can escape upward), so the bottom-corner radius
       clip that used to live on .timezone-section moves HERE — the only place
       a square cell corner could poke past the rounded card. The badge lives
       ABOVE this row, so clipping here does not re-clip it.
       2026-07-06 (user: "the compact shading has a gap on the left and right
       edges that shows white"): the row was inset inside the card's 1px border,
       so the card's white background + rounded corners peeked past the coloured
       cells at the horizontal edges. Bleed the row out by 1px on each side (and
       the bottom) so the coloured fill reaches the card's OUTER edge, and round
       the bottom corners to the card's full 13px (12px card radius + the 1px it
       now overhangs) so the fill meets the rounded outline with no white sliver. */
    overflow: hidden;
    margin-left: -1px;
    margin-right: -1px;
    margin-bottom: -1px;
    border-bottom-left-radius: 13px;
    border-bottom-right-radius: 13px;
}

body[data-layout="compact"] .compact-timeline-row .compact-hours-row {
    display: flex;
    flex-direction: row;
    flex: 1;
    /* Pin the row to the full timeline width. The base
       `body[data-layout="compact"] .compact-hours-row` rule (style.css) sets
       overflow-x:auto for the OLD scrollable compact-time-display grid; if that
       ever wins here the row would size to its scroll content and the cells —
       which only fill via flex-grow — could pack to the left leaving a gap on
       the right (user 2026-06-26: "cards … become left aligned"). width:100% +
       overflow:visible keep this card grid full-width and non-scrolling so the
       cells always stretch edge-to-edge. */
    width: 100%;
    overflow: visible;
    gap: 0;
    align-items: stretch;
    height: 36px;
    min-height: 36px;
    max-height: 36px;
    position: relative;
    scrollbar-width: none;
    align-self: auto;
}

/* Override old compact-hours-row defaults for the new timeline.
   flex:1 1 0 + min-width:0 is !important so the base scrollable-grid rule
   (style.css `.compact-hour-cell{min-width:32px;flex-shrink:0}`, and the
   responsive.css coarse-pointer touch-floor) can never win and let the 24 cells
   fall back to content width — that's what made them bunch left with a gap on
   the right after load. Equal flex-grow guarantees they always fill the card. */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    max-width: none;
    width: calc(100% / 24);
    padding: 0;
    display: flex !important;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-size: 9px;
    font-weight: 500;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
    position: relative;
    border-right: 1px solid rgba(0,0,0,0.04);
    border-radius: 0 !important;
    box-shadow: none !important;
    height: auto !important;
    grid-row: unset !important;
    grid-column: unset !important;
    border-top: none !important;
    transition: none;
}

body[data-layout="compact"] .compact-timeline-row .compact-hour-cell:last-child {
    border-right: none;
}

/* ---- Traffic light coloring (canonical: data-traffic attribute from ColorScheme) ----
   Gated to NOT paint in daynight (Local Time) mode — that mode shows the pure
   day-cycle gradient with no event-driven cell shading. Mirrors the guard the
   non-compact .timeline-cell[data-traffic] rules already carry in style.css
   (commit 0cb2710); the compact layout's equivalents were missed there, so a
   user on compact + Local Time could still see reach colours leak onto cells
   from a stale data-traffic attr. */
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell[data-traffic="green"] {
    background: var(--reach-working) !important;
}
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell[data-traffic="amber"] {
    background: var(--reach-transition) !important;
}
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell[data-traffic="sleep"] {
    background: var(--reach-sleep) !important;
}
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell[data-traffic="red"] {
    background: var(--reach-off) !important;
}

/* Current hour - blue border indicator (matching regular timeline) */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell {
    position: relative;
    z-index: 10;
    /* 2026-08-13 (user: "compact mode half missing time now label, ie :07
       instead of 11:07"). REGRESSION of the 2026-06-26 badge fix, by a new
       mechanism — the CSS below (left:50%, overflow:visible ancestors) was all
       still intact, so nothing looked wrong in this file.
       style.css `body[data-layout="compact"] .compact-hour-cell` gained
       `container-type: inline-size` on 2026-07-08 (commit 569031d7) so the
       overlap-mode labels could shrink against the cell width. But
       container-type implies `contain: layout style inline-size`, and LAYOUT
       CONTAINMENT makes the element a containing block for absolutely
       positioned descendants. The badge is position:absolute, so its left:50%
       and translateX(-50%) stopped resolving against the card and started
       resolving against this ~13px cell — shearing the leading hours off again
       and leaving ":07". It also silently broke the JS edge-clamp, which
       measures getBoundingClientRect against the CARD.
       Fix: turn containment off for the ONE cell that hosts the overhanging
       badge. Every other cell keeps container-type, so the overlap-mode
       container queries (css/overlap-mode.css) are unaffected — the current
       cell shows the now-badge, not an overlap label. */
    container-type: normal;
}

body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell::before {
    content: '';
    position: absolute;
    top: 1px;
    left: 0;
    right: 0;
    bottom: 1px;
    border: 2px solid #ec4899;
    border-radius: 4px;
    pointer-events: none;
    z-index: 25;
}

/* Live now-time badge on the compact current cell. The base .now-time-badge
   rule (style.css) sets position:absolute + translate(-50%,-100%) but NO left,
   so in compact mode it anchored to the cell's LEFT edge and the -50% pull
   sheared the leading hours off the card edge → ":42" only. We give it an
   explicit left:50% so it centres on the blue current-cell needle (the
   reference, per user: "the needle is the reference, we don't need to cut off
   the label text to fit cells"), a solid pill background so the full HH:MM is
   legible where it overhangs into the header, and white-space:nowrap so it is
   never wrapped to fit the ~13px cell. JS clamps `left` near the card edges so
   the pill never spills past the rounded card (see updateComparisonBars). */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell .now-time-badge {
    position: absolute;
    left: 50%;
    top: -2px;
    transform: translate(-50%, -100%);
    font-size: 10px;
    font-weight: 700;
    color: #db2777;
    background: var(--surface-primary, #fff);
    padding: 1px 4px;
    border-radius: 5px;
    line-height: 1.2;
    white-space: nowrap;
    pointer-events: none;
    z-index: 60;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell .now-time-badge {
    color: #fbcfe8;
    background: var(--bg-secondary, #1e293b);
}

/* Vertical NOW-LINE inside the compact current cell (2026-07-20, user: "Mobile
   mode lacks the pink time now line"). The desktop/wide timeline draws a full-
   height 1.5px pink needle (.timeline-comparison-bar, style.css #ec4899); the
   compact rows previously drew ONLY the cell border + the badge, so there
   was no needle marking the exact sub-hour "now" position the user scans against.
   This ::after is that needle: a 2px pink bar positioned at --elapsed-percent
   (the same sub-hour fraction updateComparisonBars writes for the badge/desktop
   needle), spanning the cell's full height, centred on its x via translateX(-50%).
   Matches the wide needle's #ec4899 so the two layouts read identically. Sits
   under the badge (z 26) but over the fill; the pink border ::before stays. */
/* NEEDLE OUTRANKS THE WINDOW-END DIAMOND (2026-08-17, owner: "time needle now
   no longer showing on scan").

   `◆` is `.golden-hour-end::after` in best-time-indicator.css, and it declares
   its whole geometry with !important to survive the availability/fairness
   ::after rules. That beats this block on cascade order regardless of
   specificity, so when the team window happened to END on the current hour the
   needle was not merely recoloured - its position, size and content were all
   replaced by a glyph parked above the cell.

   Both cannot share one ::after. The needle wins because it reports a fact the
   user cannot infer (where "now" falls inside this hour), whereas the window
   end is already carried by the ★ start marker, the tint across the run, and
   the tooltip. Marked !important only on the properties the diamond overrides -
   enough to hold the slot, not a blanket escalation. */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell::after {
    content: '' !important;
    position: absolute !important;
    top: 0 !important;
    bottom: 0 !important;
    left: var(--elapsed-percent, 50%) !important;
    right: auto !important;
    width: 2px !important;
    height: auto !important;
    transform: translateX(-50%) !important;
    background: #ec4899 !important;
    border: none !important;
    /* White ring so the pink needle detaches from the coloured cell it crosses
       and never reads as red (2026-07-23) — matches the wide needle + scanner. */
    box-shadow: 0 0 0 0.75px rgba(255, 255, 255, 0.9) !important;
    border-radius: 1px;
    pointer-events: none;
    z-index: 26;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell::after {
    background: #f472b6;
}

/* Current hour text styling */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-hour {
    font-weight: 700;
    box-shadow: none !important;
    border-radius: 0 !important;
}

/* Date transition */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.date-transition {
    border-left: 2px solid rgba(59, 130, 246, 0.5);
}

/* Day-change marker — stacked weekday + date number anchored at the cell top,
   matching the blue marker every other layout uses (was a black pill that
   overlapped the hour label). On a date-transition cell the hour label drops to
   the bottom so the two never collide in the ~36px cell. */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell .date-marker {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1;
    color: #2563eb;
    pointer-events: none;
    z-index: 20;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell .date-marker .day-abbr {
    font-size: 6px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell .date-marker .day-num {
    font-size: 8px;
    font-weight: 800;
}

body[data-layout="compact"] .compact-timeline-row .compact-hour-cell .time-label {
    font-size: 9px;
}

/* When a day-change marker is present, sink the hour label to the bottom of the
   cell so the marker has the top.
   Kept LEFT-aligned (2026-08-04) to match the boundary-anchored label everywhere
   else — this rule is absolutely positioned, so without the explicit left align
   it would re-centre the one label sitting on the day seam, which is precisely
   the cell where "what point does the hour change" matters most. */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.date-transition .time-label {
    position: absolute;
    bottom: 1px;
    left: 0;
    right: 0;
    text-align: left;
    padding-left: 1px;
}

body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell .date-marker {
    color: #93c5fd;
}

/* NOTE: the compact now-time badge is styled once, above (the block anchored to
   left:50% with the overhang comment). An earlier second copy of this selector
   lived here and silently overrode that block (identical specificity, later in
   source) — it forced the badge to 9px and reset its colour. Removed so the
   documented block is the single source of truth: the badge now shows a forced
   24h "HH:MM" (JS strips the 12h AM/PM suffix that was overflowing the ~13px
   cell), so its 10px size fits comfortably and reads cleanly at every phone
   width. Keep only one definition here. */

/* Faded prev/next day — EXCEPT in Local times (daynight) mode. Fading the
   whole cell with opacity lets the card's warm ambient composite through the
   day/night gradient, so a midnight-navy cell reads as MUDDY TAN on a card
   whose ambient is peach/orange — and each row fades different columns over a
   different ambient, so the same vertical time line showed vivid navy in one
   row and washed-out brown in the next (user 2026-08-05: "cell colours on
   mobile sometimes appearing at different qualities on the same time line").
   Desktop never dims other-day cells in daynight (the [data-hour] gradient
   wins there), so compact matching it also closes a renderer divergence; the
   day boundary stays conveyed by the .date-transition seam + date marker. */
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell.prev-day,
body:not([data-color-mode="daynight"])[data-layout="compact"] .compact-timeline-row .compact-hour-cell.next-day {
    opacity: 0.45;
}

/* ======== DARK MODE ======== */
body.dark-mode[data-layout="compact"] .timezone-section {
    background: var(--bg-secondary);
    border-color: rgba(255,255,255,0.06);
}

body.dark-mode[data-layout="compact"] .compact-timeline-row {
    border-top-color: rgba(255,255,255,0.06);
}

body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell {
    border-right-color: rgba(255,255,255,0.04);
    color: var(--text-tertiary);
}

/* Dark mode traffic-light colors handled by --reach-* CSS variable redefinition in style.css */
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-hour {
    font-weight: 700;
}

/* Dark mode current time cell pink border */
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.current-time-cell::before {
    border-color: #f472b6;
}

body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell .date-marker {
    color: #ffffff;
    background: rgba(0, 0, 0, 0.45);
}

body.dark-mode[data-layout="compact"] .compact-offset-pill.offset-same { background: rgba(34,197,94,0.2); color: #4ade80; }
body.dark-mode[data-layout="compact"] .compact-offset-pill.offset-close { background: rgba(59,130,246,0.2); color: #60a5fa; }
body.dark-mode[data-layout="compact"] .compact-offset-pill.offset-far { background: rgba(239,68,68,0.2); color: #f87171; }
body.dark-mode[data-layout="compact"] .compact-offset-pill.offset-medium { background: rgba(251,191,36,0.2); color: #fbbf24; }

/* ============================================
   WORKING/SLEEPING HOURS - BRACKET BORDER ONLY
   ============================================ */
/* 2026-06-26 (user: "all modes have unwanted green cell borders, I liked the
   previous minimal version"): these rules painted a loud 0.85-alpha green (and
   red) top+bottom RAIL on EVERY working/sleeping cell — and because they're more
   specific (extra .compact-timeline-row ancestor + !important) they won over the
   bracket-only base rule, so the card-stack board still read as a solid green box.
   Now bracket-only to match every other layout: interior cells bare, coloured
   arms on the .work-start / .work-end (and .sleep-start / .sleep-end) boundary
   cells ONLY. Alpha eased 0.85 → 0.45 (0.9 → 0.55 dark) to sit with the other
   layouts' brackets. */
/* Working hours - interior cells bare */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour {
    box-shadow: none !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-start {
    box-shadow:
        inset 1.5px 0 0 0 var(--cell-bracket),
        inset 0 1.5px 0 0 var(--cell-bracket),
        inset 0 -1.5px 0 0 var(--cell-bracket) !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-end {
    box-shadow:
        inset -1.5px 0 0 0 var(--cell-bracket),
        inset 0 1.5px 0 0 var(--cell-bracket),
        inset 0 -1.5px 0 0 var(--cell-bracket) !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-start.work-end {
    box-shadow: inset 0 0 0 1.5px var(--cell-bracket) !important;
}

/* Sleeping hours - interior cells bare */
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour {
    box-shadow: none !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-start {
    box-shadow:
        inset 1.5px 0 0 0 var(--sleep-bracket),
        inset 0 1.5px 0 0 var(--sleep-bracket),
        inset 0 -1.5px 0 0 var(--sleep-bracket) !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-end {
    box-shadow:
        inset -1.5px 0 0 0 var(--sleep-bracket),
        inset 0 1.5px 0 0 var(--sleep-bracket),
        inset 0 -1.5px 0 0 var(--sleep-bracket) !important;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-start.sleep-end {
    box-shadow: inset 0 0 0 1.5px var(--sleep-bracket) !important;
}

/* Dark mode - brighter bracket arms, interior still bare */
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour {
    box-shadow: none !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-start {
    box-shadow:
        inset 1.5px 0 0 0 var(--cell-bracket),
        inset 0 1.5px 0 0 var(--cell-bracket),
        inset 0 -1.5px 0 0 var(--cell-bracket) !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-end {
    box-shadow:
        inset -1.5px 0 0 0 var(--cell-bracket),
        inset 0 1.5px 0 0 var(--cell-bracket),
        inset 0 -1.5px 0 0 var(--cell-bracket) !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.working-hour.work-start.work-end {
    box-shadow: inset 0 0 0 1.5px var(--cell-bracket) !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour {
    box-shadow: none !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-start {
    box-shadow:
        inset 1.5px 0 0 0 var(--sleep-bracket),
        inset 0 1.5px 0 0 var(--sleep-bracket),
        inset 0 -1.5px 0 0 var(--sleep-bracket) !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-end {
    box-shadow:
        inset -1.5px 0 0 0 var(--sleep-bracket),
        inset 0 1.5px 0 0 var(--sleep-bracket),
        inset 0 -1.5px 0 0 var(--sleep-bracket) !important;
}
body.dark-mode[data-layout="compact"] .compact-timeline-row .compact-hour-cell.sleeping-hour.sleep-start.sleep-end {
    box-shadow: inset 0 0 0 1.5px var(--sleep-bracket) !important;
}

/* 2026-09-07 (owner, phone: "home and +1 pills on mobile compact mode remain
   in the wrong area"). Measured at 390px: .compact-card-right grew to 283px
   because .working-hours-display carried "Work 9AM - 6PM (8AM-5PM your
   time)" in one nowrap line, so .compact-card-left (flex:1, min-width:0,
   overflow:hidden) collapsed to 5px: the NAME vanished and the +1 pill sat
   jammed against the big clock. On a phone the left column keeps a floor,
   the right column a ceiling, the hours line ellipsizes, and the "(... your
   time)" note, which the timeline already shows, steps aside. */
@media (max-width: 640px) {
    body[data-layout="compact"] .compact-card-left {
        flex: 1 1 auto;
        min-width: 42%;
    }
    body[data-layout="compact"] .compact-card-right {
        flex: 0 1 auto;
        min-width: 0;
        max-width: 58%;
    }
    body[data-layout="compact"] .compact-right-meta {
        min-width: 0;
        max-width: 100%;
    }
    body[data-layout="compact"] .working-hours-display {
        min-width: 0;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    body[data-layout="compact"] .working-hours-display .working-hours-yourtime {
        display: none;
    }
    body[data-layout="compact"] .compact-big-time {
        font-size: 22px;
    }
}
@media (max-width: 640px) {
    /* The right column must be able to SHRINK below its content: the clock
       keeps its width, the status pill ellipsizes (measured: 60px clock +
       108px pill in a 124px column drew the clock over the pill).
       2026-09-09 (owner: "little of the name is visible, this is key info"):
       that overlap is already prevented by the right column's own min-width:0
       plus the pill ellipsis above. Capping the LEFT column was collateral --
       it clipped the name to "New York . Fairly..." while the right column
       sat on unused slack, because a ceiling cannot yield what it never
       claims. The left column keeps a FLOOR and takes the leftover instead. */
    body[data-layout="compact"] .compact-card-left {
        flex: 1 1 auto;
        min-width: 42%;
    }
    body[data-layout="compact"] .compact-big-time {
        flex-shrink: 0;
    }
    body[data-layout="compact"] .compact-right-meta {
        flex: 1 1 auto;
    }
    body[data-layout="compact"] .compact-right-meta .availability-status {
        display: block;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* 2026-09-07 (owner: "compact mode status cards i want the home and offset
   +3 pills to be minimal and tucked near the name"): the 26px gradient home
   box and the padded offset pill shrink to name-line ornaments that sit
   4px off the text, on every width. */
body[data-layout="compact"] .compact-card-left {
    gap: 4px;
}
body[data-layout="compact"] .compact-home-icon {
    width: 18px;
    height: 18px;
    border-radius: 5px;
    font-size: 9px;
}
body[data-layout="compact"] .compact-offset-pill {
    padding: 1px 5px;
    font-size: 9px;
    line-height: 1.2;
    margin-left: 0;
}
body[data-layout="compact"] .compact-card-left .home-lock-box {
    transform: scale(0.85);
    transform-origin: left center;
}

/* 2026-09-07 (owner: text only is acceptable): the compact layout drops the
   home box (the name reads "· You") and shows the offset as muted "+1h" text
   beside the name, an hour DIFFERENCE from you, not the zone. */
body[data-layout="compact"] .compact-home-icon {
    display: none;
}
body[data-layout="compact"] .compact-offset-pill {
    order: 2;
    padding: 0;
    background: none !important;
    border: 0;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary, #64748b) !important;
    margin-left: 6px;
}
body[data-layout="compact"] .compact-offset-pill::after {
    content: "h";
}

/* ROW ICONS SUIT THEIR CARD (2026-10-07, owner: "home and personal icon's
   make them visually suitable for their placement including when scanned").
   The person/globe marker was a fixed slate grey (#94a3b8) that vanished on
   the blue and purple cards; it now takes the name's own colour, set back, so
   it stays minimal (2026-09-11 ruling) and reads wherever the name reads,
   under the scanner too. The home tile was a teal-cyan-purple gradient with a
   glow, louder than the name beside it; it is now a quiet opaque tile with a
   teal house, legible over any card tone or the scanner's wash. */
.timezone-label .tz-type-icon,
body.dark-mode .timezone-label .tz-type-icon,
.tz-card--dark .timezone-label .tz-type-icon {
    color: currentColor;
    opacity: 0.5;
}
.timezone-label .home-icon,
body[data-layout="compact"] .compact-home-icon {
    background: #fff;
    color: #0d9488;
    box-shadow: 0 0 0 1px rgba(13, 148, 136, 0.35), 0 1px 2px rgba(15, 23, 42, 0.12);
}
.timezone-label .home-icon:hover {
    box-shadow: 0 0 0 1px rgba(13, 148, 136, 0.55), 0 1px 3px rgba(15, 23, 42, 0.18);
}

/* ONE LINE OF STATUS PER PERSON (owner 2026-10-18: "reduce compact mobile mode
   to have minimal status area, aim for little wasted space"; mock LcF6TMko,
   "as recommended"). The card header was 60px of a 97px card: a country / GMT /
   date line, a 28px clock, and two pills that truncated to "WOR..." and
   "Work 9A". Now one line: offset, City · Name (+ the SAMPLE chip), a status
   dot in the pill's own colour, the time, the menu. The status words stay in
   the DOM for screen readers; the strip's shading carries working hours, and a
   day off keeps its chip as an icon (it is also the hours editor's door). */
body[data-layout="compact"] .compact-card-header {
    padding: 0 0 0 12px;
    min-height: 44px;
}
body[data-layout="compact"] .compact-city-info {
    flex-direction: row;
    align-items: center;
    gap: 6px;
}
body[data-layout="compact"] .compact-region-date {
    font-size: 0;
    line-height: 0;
    flex-shrink: 0;
}
body[data-layout="compact"] .compact-region-date .tz-demo-badge {
    font-size: 9px;
    line-height: 1.2;
    margin-left: 0;
}
body[data-layout="compact"] .compact-big-time {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0;
}
body[data-layout="compact"] .compact-right-meta {
    order: -1;
    flex: 0 0 auto;
    flex-direction: row;
    align-items: center;
    gap: 6px;
}
body[data-layout="compact"] .compact-right-meta .availability-status {
    display: block;
    width: 9px;
    height: 9px;
    max-width: none;
    padding: 0;
    border: 0;
    border-radius: 50%;
    font-size: 0;
    background: currentColor;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.7);
}
body[data-layout="compact"] .compact-right-meta .availability-status::before,
body[data-layout="compact"] .compact-right-meta .availability-status::after {
    display: none;
}
body[data-layout="compact"] .compact-right-meta .working-hours-display:not(.off-day-pill) {
    display: none;
}
body[data-layout="compact"] .compact-right-meta .working-hours-display.off-day-pill {
    font-size: 0;
    padding: 3px 6px;
}
body[data-layout="compact"] .compact-right-meta .working-hours-display.off-day-pill .fa-calendar-xmark {
    font-size: 11px;
}
body[data-layout="compact"] .compact-right-meta .working-hours-display.off-day-pill .schedule-edit-hint {
    display: none;
}
/* Rows take their own height. flex:1 (style.css) stretched them to fill the
   list's min-height, so every pixel saved above came back as a band under the
   strip; spare room now sits once, below the last row. */
body[data-layout="compact"] .timezone-section {
    flex: 0 0 auto;
    min-height: 0;
}
/* The logo row's buttons keep their 44px; only the padding around them goes. */
body[data-layout="compact"] .app-header > .toolbar {
    padding-top: 4px;
    padding-bottom: 4px;
}

/* COMPACT, ROUND 2 (owner 2026-10-18, "Build"): the name line was 44px over a
   36px strip, the wrong way round for the densest view. Now:
   1. one tight 30px name line (the menu button keeps its width, loses height),
      over a 38px strip: rows 81px -> ~70px, a sixth person on an iPhone 13;
   2. the scan starts at the strip (comparison-column.js clips a hole per
      header), so it never covers a name, an offset or the SAMPLE chip;
   3. every hour is numbered at the foot of its cell, in the cell's own ink
      (the 68px cells centred the label below the strip's clip, in slate);
   4. the hour difference sits beside the clock ("2:06 +1h"), not mid-row.
   The header's two halves become contents so their parts can be ordered. */
body[data-layout="compact"] .compact-card-header {
    min-height: 30px;
    padding-left: 10px;
    gap: 6px;
}
body[data-layout="compact"] .compact-card-header > .compact-card-left,
body[data-layout="compact"] .compact-card-header > .compact-card-right {
    display: contents;
}
body[data-layout="compact"] .compact-card-header .compact-city-info,
body[data-layout="compact"] .compact-card-header .home-lock-box {
    order: 1;
}
body[data-layout="compact"] .compact-card-header .compact-city-info {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}
body[data-layout="compact"] .compact-card-header .compact-right-meta { order: 2; }
body[data-layout="compact"] .compact-card-header .compact-big-time { order: 3; }
body[data-layout="compact"] .compact-card-header .compact-offset-pill {
    order: 4;
    margin-left: -2px;
}
/* Dark cards: the theme's secondary grey vanished beside the clock; take the
   card's own ink, set back (2026-10-18, dark-mode pass). */
body.dark-mode[data-layout="compact"] .compact-card-header .compact-offset-pill {
    color: inherit !important;
    opacity: 0.75;
}
body[data-layout="compact"] .compact-card-header > .tz-menu-btn {
    order: 5;
    width: 36px !important;
    min-width: 36px !important;
    height: 30px !important;
    min-height: 30px !important;
    flex: 0 0 auto;
}
body[data-layout="compact"] .compact-timeline-row {
    height: 38px;
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell .time-label,
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.date-transition .time-label,
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell.date-transition-end .time-label {
    position: absolute;
    top: 27px;
    bottom: auto;
    left: 1px;
    right: auto;
    width: auto;
    padding: 0;
    font-size: 9px;
    font-weight: 600;
    line-height: 1;
    pointer-events: none;
    /* The board's day/night ink (style.css day-cycle rules), set here because
       the phone rule greys every cell's text: white on night hours, dark by day. */
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.68);
}
body[data-layout="compact"] .compact-timeline-row .compact-hour-cell:is([data-hour="6"], [data-hour="7"], [data-hour="8"], [data-hour="9"], [data-hour="10"], [data-hour="11"], [data-hour="12"], [data-hour="13"], [data-hour="14"], [data-hour="15"], [data-hour="16"], [data-hour="17"], [data-hour="18"]) .time-label {
    color: #2d3748;
    text-shadow: 0 1px 1px rgba(255, 255, 255, 0.3);
}

/* "+1h" alone (script.js / stacked-timezone-card.js 2026-10-19): only the
   stacked phone board's one-line header shows it; everywhere else the zone
   line already reads "GMT+2 (+1h)". */
.city-offset-rel {
    display: none;
}

/* THE STACKED PHONE BOARD TAKES COMPACT'S ONE-LINE HEADER (owner 2026-10-19,
   two screenshots: "I basically want the second picture's status size but
   keep the two lane events and the scanner"). The stacked level (the top of
   the phone zoom ladder) spent a 58px two-line header on each row: name,
   "GMT+1 · Mon 19 Oct", a status pill and a big clock. It now reads like the
   compact card's header (df148091): City · Name +1h on the left, a status
   dot in the pill's own colour and the time on the right, the menu at the
   edge, in compact's 30px. The timeline below it, its two lanes of event labels and
   the full scanner are untouched. The status words stay in the DOM; a day
   off keeps its chip (the hours editor's door).
   2026-10-19, later (owner, agreeing to remove condensed on phones and give
   normal this card): the same one line on the NORMAL phone level, so phones
   step normal / focus / stacked with one status card; selectors cover both
   boards (:is([data-deskstack], [data-timeline-view="current"])) and never
   focus, which keeps its name tiles.
   2026-10-19, later: "include local date per card" and "the text size can be
   slightly smaller in status area to achieve date": each card shows its own
   local day ("Tue 20") after the offset, the month dropped (the toolbar has
   it); name 13px, clock 14px, offset 10px, date 11px. Compact is no longer a
   phone level (zoom-controller.js), so phones end at focus. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-row,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]).day-cycle-enabled .timezone-section[data-current-hour] .timezone-row,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]).day-cycle-enabled.dark-mode .timezone-section[data-current-hour] .timezone-row {
        min-height: 26px; /* 30 until 2026-10-20: see the gap note at the end */
        padding-top: 0;
        padding-bottom: 0;
        align-items: center;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label {
        align-items: center;
    }
    /* No house tile or day/night glyph on the one line (stacked already drops
       them in style.css); the name already reads "· You". */
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .home-icon-wrapper,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .day-night-indicator {
        display: none;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-name {
        font-size: 13px;
        font-weight: 600;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label > div:last-child {
        display: flex;
        flex-direction: row;
        /* ONE LINE, OFFSET AND DAY ALWAYS SHOWN (owner 2026-10-19: "the one
           line should include day and offset even if small text"). Text steps
           down on narrow phones (below); "+1h" and "Mon 19" never shrink, so
           only a long name gives way, with an ellipsis, at the narrowest. */
        flex-wrap: nowrap;
        align-items: center;
        gap: 6px;
        max-width: none;
        min-width: 0;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-name-row {
        flex: 0 1 auto;
        min-width: 0;
        overflow: hidden;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-name-row .city-name {
        display: block;
        max-width: 100%;
        /* The editable name carries padding 2px 6px cancelled by -6px side
           margins (its hover box); under max-width:100% that clipped 12px off
           every name ("London ·…" with room to spare). Sides zeroed here. */
        margin-left: 0;
        margin-right: 0;
        padding-left: 0;
        padding-right: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset {
        display: inline-flex;
        flex: 0 0 auto;
        align-items: center;
        gap: 6px;
        max-width: none;
        overflow: visible;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset::after {
        content: none;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset-zone,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-region-country,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-date-month {
        display: none;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-date {
        display: inline;
        flex: 0 0 auto;
        max-width: none;
        overflow: visible;
        margin: 0;
        font-size: 11px;
        font-weight: 500;
        opacity: 0.75;
        white-space: nowrap;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset-rel {
        display: inline;
        font-size: 10px;
        font-weight: 600;
        opacity: 0.75;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info {
        flex-direction: row;
        align-items: center;
        gap: 8px;
    }
    /* THE REAL STATUS PILL, NOT A DOT (owner 2026-10-20: "real status pills I
       dont like the badly aligned icon in circle"; the dot before it was "too
       vague"). The one line shows the board's own pill ("Working -> 5pm", its
       dot, the holiday and Pending tabs), a step smaller to sit in the line. */
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info .availability-status {
        flex: 0 0 auto;
        font-size: 8px;
        letter-spacing: 0.02em;
        height: 18px;
        min-height: 0;
        padding: 0 6px;
        gap: 3px;
        line-height: 1;
        white-space: nowrap;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info .current-time-large {
        font-size: 14px;
        font-weight: 700;
        line-height: 1;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info .current-time-ampm {
        font-size: 9px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-right .tz-menu-btn {
        top: -1px;
    }
}

/* FOCUS NAME TILE: THE CARD'S LOCAL DATE (owner 2026-10-19: "include local
   date per card"; focus is now the lowest phone level). A third line under
   who/where, "Mon 19", at the place line's size (renderCompactName). */
body[data-focus-mode] .compact-name--multiline .compact-name-date {
    display: block;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 600;
    opacity: 0.78;
    font-size: 7.5px;
    letter-spacing: 0.1px;
    margin-top: 1px;
}
body[data-focus-mode] .compact-name.compact-name--long .compact-name-date {
    font-size: 6.5px;
}
/* "Mon 19 · +1h" reads in the cards' own case, not the tile's capitals
   ("+1H"); owner 2026-10-20: "status cards should have date and offset when
   possible". */
body[data-focus-mode] .compact-name--multiline .compact-name-date {
    text-transform: none;
}

/* CONDENSED CARD: THE DATE COMES BACK, ON THE OFFSET'S LINE (owner
   2026-10-19: "include local date per card"; supersedes the 2026-08-25
   hide in style.css ≈879, which kept condensed dense by dropping it). Same
   one quiet line as the normal card (style.css ≈914): "GMT+2 (+1h) · Mon 19
   Oct" there, "Mon 19" here (no month: the dense level, and at 320px the
   month ran under the status column), so the card gains no height. The
   weekday chip stays hidden (the day is the date's first word). */
body[data-timeline-view="minimal"] .timezone-label .city-date-month {
    display: none;
}
body[data-timeline-view="minimal"] .timezone-label .city-offset,
body[data-timeline-view="minimal"] .timezone-label .city-date {
    display: inline;
    font-size: 11px;
    opacity: 0.8;
    color: var(--text-secondary, #64748b);
}
body[data-timeline-view="minimal"] .timezone-label .city-offset::after {
    content: " · ";
    opacity: 0.55;
}

/* The one-line header (stacked + normal) on narrow phones: the same line in smaller text
   (owner 2026-10-19: "include day and offset even if small text"). */
@media (max-width: 380px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label > div:last-child {
        gap: 4px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-name {
        font-size: 12px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset-rel {
        font-size: 9px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-date {
        font-size: 10px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info {
        gap: 6px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info .current-time-large {
        font-size: 13px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-time-info .current-time-ampm {
        font-size: 8px;
    }
}

/* STATUS LINE: LARGER NAMES ON NORMAL, LESS GAP TO THE GLYPHS (owner
   2026-10-20: "the largest zoom one the names should be larger slightly. Have
   minimal gap space between status text and bedtimes and now times glyph").
   - Normal (the most zoomed-in phone level) names 15px (14px under 380px);
     stacked keeps 13px (12px), it fits the whole day.
   - The one line is 26px (was 30): the glyph band (now-time badge, star and
     diamond, day markers, the sleep bracket tops) starts right under the
     text. Measured before: 5px name-to-glyph on normal, 12px on stacked,
     whose timeline row kept a 16px reserve (style.css "Every row reserves
     it") where normal uses 8px; stacked now takes normal's 8px. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"][data-timeline-view="current"]:not([data-deskstack="on"]):not([data-focus-mode]) .timezone-label .city-name {
        font-size: 15px;
    }
    body[data-mobile-board="deskpan"][data-deskstack="on"]:not([data-focus-mode]) .timezone-section .timeline-row {
        margin-top: 8px !important;
    }
    /* The sticky name block reserved room for the two-line status cluster
       (style.css: 100vw - 166px, measured 132-135px at 320); the one-line dot
       + clock + menu measure ~98px, so the name gets the difference (at 320
       four of five names were cut with 58px free before the clock). */
    body[data-mobile-board="deskpan"][data-timeline-view="current"]:not([data-deskstack="on"]):not([data-focus-mode]) .timezone-label {
        max-width: calc(100vw - 120px);
        width: calc(100vw - 120px);
    }
}
@media (max-width: 380px) {
    body[data-mobile-board="deskpan"][data-timeline-view="current"]:not([data-deskstack="on"]):not([data-focus-mode]) .timezone-label .city-name {
        font-size: 14px;
    }
}

/* EVENTS CLEAR THE HOUR NUMBERS (owner 2026-10-20, stacked screenshot: "The
   events slightly cover the numbers"). Measured in the 68px row: lane two runs
   32-60px and sits above the cells (z 97), the hour numbers at 57-69px, so a
   lower-lane chip covered their tops. The lanes are shared by every level and
   pinned by guards, so the ROW grows instead, on the two phone levels with the
   one-line card only: 74px puts the numbers at 63px, clear of lane two, and the
   26px line + stacked's 8px gap (above) already paid for it. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) {
        --timeline-row-height: 74px;
    }
}

/* ONE FLEXIBLE LINE FOR THE REAL PILL (owner 2026-10-20: "real status pills").
   The pill is wider than the dot it replaces and its width varies (a holiday
   tab, Pending), so the name block's fixed width (100vw - 120px, sized for the
   dot) would run under it. The line is one row that stays on screen, 2px in
   from each edge past the card's 1px border and 4px padding (-5px, MINIMAL SIDE
   SPACE below), at every pan: the name block takes what the pill and clock
   leave and only a name that cannot fit gives way. Pinched (the fitted
   zoomed-out level, or a pinch) the line rides with its card, as the name
   block already does there. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-row {
        position: sticky;
        left: 2px;
        margin-left: -5px;
        /* The same past the right side: a sticky box stays inside its card's
           content box, so at the right end the line was held 5px short. */
        margin-right: -5px;
        width: calc(100vw - 4px);
        max-width: calc(100vw - 4px);
        box-sizing: border-box;
        padding-left: 6px;
        padding-right: 4px;
        justify-content: flex-start;
        gap: 6px;
        z-index: 1;
        /* The row's 4px day-part accent stuck at the line's left edge. */
        border-left-width: 0;
        border-radius: 0;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-label {
        position: relative;
        left: auto;
        flex: 1 1 auto;
        width: auto;
        max-width: none;
        min-width: 0;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-right {
        position: relative;
        right: auto;
        flex: 0 0 auto;
        margin-left: auto;
    }
    /* When the tick splits the clock into digits + am/pm, the base rule
       (style.css, "consistent width") holds the digits at 85px. */
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-time-info .current-time-digits {
        min-width: 0;
    }
    /* The am/pm keeps a 28px box from the same base rule; on one line it only
       needs its text. */
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-time-info .current-time-ampm {
        width: auto;
        margin-left: 2px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-time-info {
        gap: 5px;
    }
}
body[data-mobile-board="deskpan"] #deskpan-zoom-layer[style*="--deskpan-pinch"] .timezone-section .timezone-row {
    position: relative;
    left: auto;
    margin-left: 0;
    margin-right: 0;
    width: auto;
    max-width: none;
}

/* MINIMAL SIDE SPACE ON EVERY ZOOM LEVEL (owner 2026-10-20: "The edge's of all
   zoom modes status cards should have minimal side space on all"). The base
   card is `margin: 2px 12px 8px` with 12px side padding, and on the phone board
   it is also at least 100% wide (style.css, "Section spans the FULL board
   width"), so it overflowed the board by its 24px of margin: at the right end
   every card was cut 12px past the screen, and at the left end the track
   started 25px in (measured on normal, focus and the fitted level). Phones:
   2px margins, 4px side padding, and a minimum width that leaves the margins
   room. The fitted level reads the cards, so it fits them to 2px too. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"] #timezone-list .timezone-section {
        margin-left: 2px !important;
        margin-right: 2px !important;
        padding-left: 4px !important;
        padding-right: 4px !important;
        min-width: calc(100% - 4px) !important;
    }
}

/* THE ⋮ USES THE SPACE THAT IS THERE (owner 2026-10-21: "Can we reduce unused
   space added tp the right status card's. The 3 dots can use the existing
   space. Move the time etc leftwards to accommodate rather than adding
   space"). The menu was a 28px box hung 6px past the cluster, and the time
   block kept 24px of padding for it (style.css, "the absolute menu"), most of
   it empty beside a 4px glyph. On the one-line card the box is 12px and the
   padding 12px, so the clock and pill sit that much nearer the edge; an
   invisible 28 x 44px area keeps it a thumb target. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-time-info {
        padding-right: 12px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-right .tz-menu-btn {
        width: 12px;
        min-width: 12px;
        right: -2px;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-section .timezone-right .tz-menu-btn::after {
        content: '';
        position: absolute;
        top: -6px;
        bottom: -6px;
        left: -8px;
        right: -8px;
    }
}

/* FOCUS: EVENTS CLEAR THE HOUR NUMBERS (owner 2026-10-21: "Increase focus mode
   cells or decrease event size to prevent overlap of hour by hour cell
   labels", screenshot: a "Focus Block 9:44-12:44" chip over hours 10-17).
   The 23px chip (style.css, "Fit events within the 36px focus timeline") was
   sized when the numbers were 7px; they are now 10px (one size for every
   hour since 2026-10-23; 10.8px when this was written), their top at ~25px
   in the 36px row, under a chip running 4-27px. The chip is 19px (4-23)
   on phones, title over time still fitting in it; the row keeps its height. */
@media (max-width: 640px) {
    body[data-focus-mode][data-mobile-board="deskpan"] #timezone-list .timeline-event-marker,
    body[data-focus-mode][data-mobile-board="deskpan"] #timezone-list .timeline-event-marker.stack-0,
    body[data-focus-mode][data-mobile-board="deskpan"] #timezone-list .timeline-event-marker.stack-1 {
        height: 19px !important;
    }
}

/* THE ZOOMED-OUT LEVEL'S TOP RESERVE SHRINKS WITH THE BOARD (v1611, measured
   by another session: a ~90px blank band between the summary row and the scan
   presets). #timezone-list reserves the fixed chrome plus the scan controls'
   overhang above the first card (style.css, padding-top); fitted, the controls
   are drawn at the board's scale (PinchZoomController writes --fit-scale), so
   only the overhang is scaled; the chrome terms stay as they are. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"][data-fit-day="on"] #timezone-list {
        padding-top: calc(var(--deskpan-chrome-h, 208px) + var(--deskpan-scanner-overhang) * var(--fit-scale, 1)
            - var(--deskpan-chrome-slack) + var(--deskpan-chrome-deficit)) !important;
    }
}

/* THE OFFSET AFTER THE DATE, ON EVERY ROW (owner 2026-10-21: "Why not include
   the time offset in status areas. We have room except focus mode", then
   "After date. Live doesn't have offsets on any zoom level"). The one line
   read "City · Name +1h Tue 20", and your own row showed no offset at all
   (its relative offset is 0, so no "+1h" span; the zone is hidden on the
   line), which on a board of just you is every row. Now the date comes first
   and the offset after it: "+1h" for others, your own zone ("GMT+1") for you,
   as focus's name tiles already show. Normal and the zoomed-out level (the
   same card, drawn smaller); focus keeps its tiles. */
@media (max-width: 640px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-name-row {
        order: 0;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-date {
        order: 1;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset {
        order: 2;
    }
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset:not(:has(.city-offset-rel)) .city-offset-zone {
        display: inline;
        white-space: nowrap;
    }
    /* Set like the date it follows (owner: "It should looks like the data in
       size and position"): the offset was 10px / 600 on a 12px line, the
       date 11px / 500 on 13.2px, so it read smaller and sat 2px lower. */
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset-rel,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset:not(:has(.city-offset-rel)) .city-offset-zone {
        font-size: 11px;
        font-weight: 500;
        line-height: 1.2;
        opacity: 0.75;
    }
}
@media (max-width: 380px) {
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset-rel,
    body[data-mobile-board="deskpan"]:is([data-deskstack="on"], [data-timeline-view="current"]):not([data-focus-mode]) .timezone-label .city-offset:not(:has(.city-offset-rel)) .city-offset-zone {
        font-size: 10px;
    }
}
