@import url("./site-tokens.css");

/* Reset and base styles */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {


  /* FAHDS-206 entry category palette. The list of categories is js/log-categories.mjs;
     test/log-categories.test.mjs checks every value has a dot token and a .cat-<v> class, every
     heat map value has steps 1-5, and every dot is at least 3:1 on white.
     Standard heat map steps (FAHDS-207): 0 -> --cat-empty, <1h -> 1, 1-2h -> 2, 2-4h -> 3, 4-6h -> 4, 6h+ -> 5.
     Exercise: <1h -> 1, 1-2h -> 2, 2-3h -> 3, 3h+ -> 5 (token 4 remains available).
     Sleep: <5h red, 5-6h orange, 6-7h yellow, 7-8h light green, 8h+ green. */
  --cat-empty: #eeeff1;
  --cat-study-1: #e3ffeb;    --cat-study-2: #ceffd9;    --cat-study-3: #a8edb8;    --cat-study-4: #63c87f;    --cat-study-5: #328f57;
  --cat-exercise-1: #ffe6e8; --cat-exercise-2: #ffccd0; --cat-exercise-3: #ffb3ba; --cat-exercise-4: #e9858e; --cat-exercise-5: #be5e67;
  --cat-reading-1: #fff1df;  --cat-reading-2: #ffe8cc;  --cat-reading-3: #ffdfba;  --cat-reading-4: #e9ad77;  --cat-reading-5: #af7543;
  --cat-social-1: #e7ddff;   --cat-social-2: #d8caff;   --cat-social-3: #c8b6ff;   --cat-social-4: #9f82e2;   --cat-social-5: #7252bb;
  --cat-work-1: #f4f8ff;     --cat-work-2: #e3edff;     --cat-work-3: #9ac5e7;     --cat-work-4: #69a8d8;     --cat-work-5: #4577b0;
  --cat-entertainment-1: #efd8f7; --cat-entertainment-2: #dca9ed; --cat-entertainment-3: #b253d8; --cat-entertainment-4: #9239b7; --cat-entertainment-5: #6d278b;
  --cat-sleep-1: #d9534f; --cat-sleep-2: #ef8a3c; --cat-sleep-3: #f2c744; --cat-sleep-4: #a6d66f; --cat-sleep-5: #3f9a5a;
  --cat-study-base: var(--cat-study-3); --cat-exercise-base: var(--cat-exercise-3); --cat-reading-base: var(--cat-reading-3);
  --cat-social-base: var(--cat-social-3); --cat-work-base: var(--cat-work-2); --cat-entertainment-base: var(--cat-entertainment-2);
  --cat-study-dot: var(--cat-study-5); --cat-exercise-dot: var(--cat-exercise-5); --cat-reading-dot: var(--cat-reading-5);
  --cat-social-dot: var(--cat-social-5); --cat-work-dot: var(--cat-work-5); --cat-entertainment-dot: var(--cat-entertainment-5);
  --cat-sleep-dot: #6f7f9c;   /* slate */
  --cat-other-dot: #8a8f98;   /* grey */
  --cat-exercise-tile: #ffb3ba;
}

/* FAHDS-206: one class per category sets --cat-dot; shared by /log and /pomo. */
.cat-study { --cat-dot: var(--cat-study-dot); --cat-popup: var(--cat-study-4); }
.cat-exercise { --cat-dot: var(--cat-exercise-dot); --cat-popup: var(--cat-exercise-4); }
.cat-reading { --cat-dot: var(--cat-reading-dot); --cat-popup: var(--cat-reading-4); }
.cat-social { --cat-dot: var(--cat-social-dot); --cat-popup: var(--cat-social-4); }
.cat-work { --cat-dot: var(--cat-work-dot); --cat-popup: var(--cat-work-3); }
.cat-entertainment { --cat-dot: var(--cat-entertainment-dot); --cat-popup: var(--cat-entertainment-3); }
.cat-sleep { --cat-dot: var(--cat-sleep-dot); }
.cat-other { --cat-dot: var(--cat-other-dot); }

html {
  font-size: 16px;
  line-height: 1.6;
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-sans);
  font-size: 1.1rem;
  font-weight: 500;
  background-color: var(--color-bg);
  color: var(--color-text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: var(--color-link);
  text-decoration: none;
  transition: color 0.2s ease;
}

a:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

img {
  max-width: 100%;
  height: auto;
}

/* Layout */
.container {
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--spacing);
}

/* Header / Nav */
.site-header {
  padding: 2rem 0 0;
}

.nav-container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--spacing);
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.nav-links {
  list-style: none;
  display: flex;
  gap: 1.5rem;
}

.nav-links a {
  color: var(--color-text);
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
}

.nav-links a:hover {
  color: var(--color-text-light);
  text-decoration: none;
}

.nav-links a.active {
  color: var(--color-text);
  font-weight: 500;
}

/* ECG row: photo + heartbeat line */
.ecg-row {
  display: flex;
  align-items: center;
  gap: 0;
  margin-top: 3rem;
  margin-bottom: 0.5rem;
}

.ecg-wrap {
  flex: 1;
  position: relative;
}

.ecg-canvas {
  width: 100%;
  height: 72px;
  display: block;
}

/* Homepage intro */
.intro-photo {
  width: 72px;
  height: 72px;
  border-radius: 8px;
  object-fit: cover;
  object-position: center top;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}

.location {
  font-size: 0.85rem;
  color: var(--color-text-light);
}

.hr-status {
  position: absolute;
  top: 2px;
  right: 0;
  font-size: 0.7rem;
  color: var(--color-text-light);
}

.hr-heart {
  display: inline-block;
  color: #666;
  transition: transform 0.1s ease-out;
  transform: scale(1);
}

.hr-heart.pulse {
  transform: scale(1.2);
}

.hr-updated {
  position: absolute;
  bottom: 2px;
  right: 0;
  font-size: 0.65rem;
  color: var(--color-text-light);
  opacity: 0.7;
}

.intro {
  padding: 0rem 0 6rem;
}

.intro h1 {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 700;
  margin-bottom: 2rem;
  line-height: 1.2;
  color: var(--color-text);
}

.intro p {
  font-size: 1.1rem;
  line-height: 1.6;
  margin-bottom: 1rem;
  color: var(--color-text);
}

.intro a,
.post-content a,
.project-item a {
  color: var(--color-text);
  background: var(--color-link-highlight);
  border: none;
  border-radius: 4px;
  padding: 0.1em 0.35em;
  text-decoration: none;
  transition: background 0.2s ease;
}

.intro a:hover,
.post-content a:hover,
.project-item a:hover {
  background: var(--color-link-highlight-hover);
  text-decoration: none;
}

.intro a.project-tag {
  background: none;
  border: none;
  padding: 0;
}

.intro a.project-tag:hover {
  background: none;
}

/* Projects list on homepage */
.projects-heading {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 0.4rem;
}

.projects-bullets {
  list-style: disc;
  padding-left: 1.5rem;
  margin-bottom: 1rem;
  font-size: 0.95rem;
}

.projects-bullets li {
  margin-bottom: 0.75rem;
}

.project-desc {
  display: block;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--color-text-light);
  margin-top: 0.15rem;
}

.projects-more {
  font-size: 0.85rem;
  color: var(--color-text-light);
}

/* Project tags (inline pill with hover preview) */
.project-tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0;
  background: none;
  border: none;
  border-radius: 4px;
  padding: 0;
  font-size: inherit;
  line-height: 1.4;
  vertical-align: middle;
  text-decoration: none;
  color: var(--color-text);
}

.project-tag:hover {
  text-decoration: none;
  color: var(--color-text);
}

.project-tag-img {
  width: 1.4em;
  align-self: stretch;
  border-radius: 3px 0 0 3px;
  background-size: cover;
  background-position: center;
  flex-shrink: 0;
}

.project-tag-img.contain {
  background-size: contain;
  background-repeat: no-repeat;
}

.project-tag-text {
  background: #fef9e7;
  border: 1px solid #f0e6b8;
  border-left: none;
  border-radius: 0 4px 4px 0;
  padding: 0.1em 0.4em;
  transition: background 0.2s ease;
}

.project-tag-text:first-child {
  border-left: 1px solid #f0e6b8;
  border-radius: 4px;
}

.project-tag:hover .project-tag-text {
  background: #fdf0c4;
}


.section-divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: 1rem 0;
}

/* Page header */
.page-header {
  padding: 3rem 0 2rem;
}

.page-header h1 {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--color-text);
}

/* Booking uses the shared site content width. */
.booking-page { padding-top: 3rem; padding-bottom: 4rem; }
.booking-region {
  position: relative;
  --booking-pale: #eff5ff;
  --booking-blue: var(--color-link-hover);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  font-size: 0.9375rem;
}
/* FAHDS-185 amendment 3 (owner: "this style", "no background or box shadow"): the
   booking surface is not a card at any width. The border, the 12px radius, the
   shadow and the opaque background are all gone - the page background shows
   through, and the only structure left is .booking-identity's border-bottom,
   which STAYS (it is the divider under the host name in the owner's screenshot).
   Horizontal padding goes with the card: it was a card inset, and <main> is
   already .container (shared maximum width, 1.5rem side padding), so 24px of extra
   inset pushed the booking content out of line with the site header and nav.
   Zero here means the calendar lines up with the nav exactly, and the gutter at
   390px is .container's own 24px - never flush to the edge. Vertical rhythm is
   unchanged. */
.booking-identity, .booking-scheduler { min-width: 0; padding: 24px 0; }
.booking-identity { display: grid; grid-template-columns: 48px minmax(0, 1fr); column-gap: 14px; border-bottom: 1px solid var(--color-border); }
.booking-portrait { grid-row: 1 / 4; display: block; width: 48px; height: 48px; object-fit: cover; object-position: center 35%; border-radius: 50%; }
.booking-host { color: var(--color-text-light); margin: 0 0 0.15rem; font-size: 0.8125rem; }
.booking-identity h1 { font-family: var(--font-sans); font-size: 1.35rem; line-height: 1.3; font-weight: 650; margin: 0 0 0.35rem; letter-spacing: -0.035em; }
/* grid-column: 2 keeps it in the text column. The portrait spans rows 1-3 of
   column 1, so without this the date lands in the 48px column under the
   portrait and wraps. */
.booking-selected-date { grid-column: 2; display: flex; align-items: flex-start; gap: 0.5rem; margin: 0.5rem 0 0; font-size: 0.9375rem; color: var(--color-text); }
/* FAHDS-199 (cal.com cue): a decorative calendar icon beside the date (bold) and the
   time range (muted) on two lines. `hidden` still wins over display: flex above -
   .booking-region [hidden] is (0,2,0) against this rule's (0,1,0). The time line is
   empty while a day is chosen but no time yet, and then takes no space. */
.booking-selected-icon { flex: 0 0 auto; margin-top: 0.2em; color: var(--color-text-light); }
.booking-selected-lines { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.booking-selected-day { font-weight: 600; }
.booking-selected-time { font-weight: 500; color: var(--color-text-light); }
.booking-selected-time:empty { display: none; }
/* Kept in the DOM and non-empty: it names #booking-times-panel via
   aria-labelledby. The sighted reader gets the same date from a visible element,
   but not always the same one: the page header carries it on desktop, while at
   <=700px the header date is hidden during the times stage (in the 700px query) and
   .booking-slots-day above the slot list carries it instead. */
#booking-slots-heading { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.booking-stages { display: grid; }
.booking-stages > * { grid-area: 1 / 1; min-width: 0; }
/* FAHDS-185: the `overflow-x: clip` that used to live here existed only to clip
   the times panel's 100% horizontal slide. That slide is gone (one fade+rise
   language across every stage), so the clip - and the focus-scroll container it
   risked creating - goes with it. */
.booking-stages[data-stage="times"] > #booking-underlay { visibility: hidden; }
/* FAHDS-185: one animation per data-stage value. Changing the attribute changes
   animation-name, which restarts the animation - so every move between stages,
   forwards AND backwards, gets the same short entrance. Animating the container
   rather than the panes means nothing is ever painted after it has been retired,
   so no pane is ever visible-but-inert or inert-but-visible. */
.booking-stages[data-stage="calendar"] { animation: booking-stage-calendar 200ms ease-out; }
.booking-stages[data-stage="times"] { animation: booking-stage-times 200ms ease-out; }
.booking-stages[data-stage="details"] { animation: booking-stage-details 200ms ease-out; }
.booking-stages[data-stage="result"] { animation: booking-stage-result 200ms ease-out; }
@keyframes booking-stage-calendar { from { opacity: 0; transform: translateY(6px); } }
@keyframes booking-stage-times { from { opacity: 0; transform: translateY(6px); } }
@keyframes booking-stage-result { from { opacity: 0; transform: translateY(6px); } }
/* Opacity only, no transform: the Turnstile iframe renders into this subtree at
   the end of showStage('details') and must never sit inside a transforming
   element - see the long comment at the end of showStage() in js/booking.mjs. */
@keyframes booking-stage-details { from { opacity: 0; } }
/* FAHDS-187 (plan review P2): the stage container's entrance is suppressed for the
   INITIAL unhide of #booking-calendar. data-stage="calendar" ships in the markup,
   so booking-stage-calendar would otherwise run when js/booking.mjs clears the
   root's `hidden` - and a fast availability response would reveal the grid while
   its container is still rising past the stationary skeleton. js/booking.mjs adds
   this class before that unhide and removes it on the first real stage change,
   which then animates normally. */
.booking-region .booking-stages.booking-stages-initial { animation: none; }
/* The entrance a visitor actually sees first: the grid appears when load() clears
   `hidden` here, so that is where the first real entrance has to live. Do not
   "fix" the stage animation instead.
   FAHDS-187: opacity only, no transform. #booking-skeleton holds this exact
   footprint until the reveal and fades out over the same 200ms (see
   .booking-skeleton-exit), so the two read as one crossfade; any rise would slide
   the real tiles past their placeholders.
   FAHDS-185 (review R3): gated on a class load() sets for the FIRST reveal only.
   Later reveals (Retry, a conflict reload) swap instantly with the skeleton, and
   a reveal that lands in the same frame as a data-stage change would still square
   the opacity ramp. Only this first one is worth animating. */
#booking-content.booking-content-enter:not([hidden]) { animation: booking-content-in 200ms ease-out; }
@keyframes booking-content-in { from { opacity: 0; } }
.booking-region h2 { font-size: 1.2rem; margin: 0 0 1.5rem; font-weight: 650; letter-spacing: -0.025em; }
/* Keep availability, recovery and no-JS visibility independent of layout. */
.booking-region [hidden] { display: none; }
.booking-region button {
  font: inherit;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  min-height: 44px;
  cursor: pointer;
}
.booking-region button:focus-visible,
.booking-region input:focus-visible,
.booking-region textarea:focus-visible,
.booking-region summary:focus-visible {
  outline: 2px solid var(--booking-blue);
  outline-offset: 3px;
}
/* After a click or tap there are no rings at all (owner request); js/booking.mjs sets
   data-input. Tab or an arrow key restores them, so keyboard users keep their place. */
:root[data-input="pointer"] .booking-region :focus-visible { outline: none; }
/* Programmatic focus targets, not controls: focused by script so screen readers announce
   them. They never get a visible ring. */
#booking-form-status:focus, #booking-result-heading:focus, #booking-slots-heading:focus { outline: none; }
.booking-region button:hover:not(:disabled):not([aria-disabled="true"]) { border-color: var(--booking-blue); }
.booking-region button:disabled, .booking-region button[aria-disabled="true"] { cursor: default; color: var(--color-text-light); }
.booking-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
.booking-layout > section { min-width: 0; min-height: 0; }
.booking-month-nav { display: flex; align-items: center; justify-content: space-between; gap: 0.25rem; margin-bottom: 1rem; }
.booking-month-arrows { display: flex; gap: 0.25rem; }
/* FAHDS-199 (cal.com cue): quiet grey chevrons with a neutral hover, the disabled one
   fainter still. The blue stays on the tiles. The first disabled colour is the
   fallback where color-mix is unsupported; aria-disabled semantics are unchanged. */
.booking-region .booking-month-arrows button { width: 36px; min-height: 40px; padding: 0; border: 0; border-radius: 50%; color: var(--color-text-light); font-size: 1.6rem; line-height: 1; }
.booking-region .booking-month-arrows button[aria-disabled="true"] { color: #c4c4c4; color: color-mix(in srgb, var(--color-text-light) 35%, var(--color-bg)); }
.booking-region .booking-month-arrows button:hover:not([aria-disabled="true"]):not(:disabled) { background: #f2f2f2; color: var(--color-text); }
#booking-slots-heading { font-size: 0.9375rem; font-weight: 500; margin: 0; }
/* FAHDS-199: bold month name, muted year - two spans written by renderMonth(). The
   nav's height is still set by the arrow buttons (16px x 1.6 is under 40px), and the
   skeleton's heading placeholder is untouched, so the swap cannot shift. */
.booking-month-nav h3 { font-size: 1rem; font-weight: 400; margin: 0; letter-spacing: -0.01em; }
.booking-month-name { font-weight: 650; color: var(--color-text); }
.booking-month-year { font-weight: 400; color: var(--color-text-light); }
#booking-slots-heading { min-width: 0; overflow-wrap: anywhere; }
/* Above 700px the times surface replaces the calendar in the same intrinsic grid
   area; at or below it the grid un-stacks and this lays out underneath a calendar
   that stays live. Its entrance is the container animation above (desktop) or
   booking-slots-reveal (stacked). */
/* FAHDS-185 amendment 3: no background. It was here for the slide-over, which no
   longer slides over anything - desktop, #booking-underlay is visibility:hidden
   for the whole times stage, and stacked the panel is ordinary in-flow content
   under the calendar. Nothing is painted behind it to mask. */
.booking-times-panel { z-index: 1; margin: 0; color: var(--color-text); }
/* FAHDS-185: the terse visible day label ("Mon 14th"), stacked layout only. It is
   aria-hidden in the markup: #booking-slots-heading already names the panel and
   speaks the same date in full, so this adds no second announcement. */
.booking-slots-day { display: none; margin: 0; }
.booking-times-meta { padding: 0 6px 6px; }
.booking-times-header { display: flex; flex: 0 0 auto; align-items: center; justify-content: space-between; gap: 12px; padding-inline: 6px; }
.booking-times-header button { flex: 0 0 auto; }
/* The heading is visually hidden and out of flow, so space-between leaves Back
   at the left and the copy control at the right of the same row. Stacked, Back is
   `hidden` and the visible day label takes the left of that row instead. */
.booking-region #booking-copy-date { display: inline-flex; align-items: center; gap: 0.375rem; font-size: 0.8125rem; padding: 0.5rem 0.625rem; }
#booking-copy-date .booking-copy-icon, #booking-copy-date .booking-copy-check { flex: 0 0 auto; }
#booking-copy-date .booking-copy-check { display: none; }
.booking-region #booking-copy-date[data-copied="true"] { background: var(--color-border); border-color: var(--color-border); color: var(--color-text-light); }
#booking-copy-date[data-copied="true"] .booking-copy-icon { display: none; }
#booking-copy-date[data-copied="true"] .booking-copy-check { display: inline; }
#booking-times-status { font-size: 0.8125rem; margin: 0.5rem 0 0; overflow-wrap: anywhere; }
#booking-times-status:empty { margin: 0; }
/* Full column width at every size (owner, replacing an earlier 22rem cap): the grid,
   the weekday row and the month nav above all span the same content column, so the arrows
   sit over the Saturday column. Tiles are capped in .booking-day instead, so they do not
   balloon. Do not reintroduce a max-width on only some of the three - that is what left
   the arrows stranded at the far edge of a narrower grid. */
/* FAHDS-199 (owner, cal.com cue): the grid uses a small, equal gap both ways.
   Tiles fill their tracks up to the cap in .booking-day and stay centred as the
   content column grows. The weekday row shares the gap, so its labels stay centred
   over the tile columns; text-indent offsets the letter-spacing trailing each label. */
.booking-weekdays, .booking-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
.booking-weekdays { text-align: center; font-size: 0.75rem; font-weight: 500; letter-spacing: 0.08em; text-indent: 0.08em; text-transform: uppercase; color: var(--color-text); margin-bottom: 0.75rem; }
/* FAHDS-185: rounded squares, not circles (owner, cal.com reference). The base
   rule already paints unavailable, past and out-of-window days as bare numbers -
   `background: transparent` with no tile, at 400 weight since FAHDS-199 - and
   .available/[aria-pressed] below fill and invert them. Do not add colours here.
   Day numbers are 1.25rem (1.125rem at <=700px, where tiles shrink to ~44px and the
   today dot must still clear the number) - slightly larger than body text (owner). */
/* FAHDS-187: #booking-skeleton's tiles share this rule (and the <=700px one) so the
   skeleton -> calendar swap cannot shift. Do not split the selector lists. */
.booking-region .booking-day,
.booking-region .booking-skeleton-days > span { justify-self: center; width: 100%; max-width: 78px; aspect-ratio: 1; min-height: 0; border: 0; border-radius: 10px; padding: 0; line-height: 1; font-size: 1.25rem; font-weight: 400; background: transparent; color: var(--color-text-light); }
/* FAHDS-185: today's marker. A ::after with empty content never enters the
   accessibility tree, so the dot is silent by construction and the button's
   aria-label stays the plain date - do NOT add ", today" to that label.
   currentColor makes it grey on a bare day, blue on an available tile and white
   on the selected one, with no extra rules. FAHDS-199: bottom is a percentage so the
   dot sits under the number on a 78px desktop tile as well as a 44px mobile one. */
.booking-region .booking-day[data-today] { position: relative; }
.booking-region .booking-day[data-today]::after {
  content: ""; position: absolute; left: 50%; bottom: 16%; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: currentColor;
}
.booking-region .booking-day.available { color: var(--booking-blue); background: var(--booking-pale); font-weight: 650; }
.booking-region .booking-day.available:hover:not(:disabled) { background: #dce9ff; }
.booking-region .booking-day.spillover { visibility: hidden; }
.booking-region .booking-day[aria-pressed="true"],
.booking-region .booking-day[aria-pressed="true"]:hover:not(:disabled) { color: #fff; background: var(--booking-blue); }
/* FAHDS-199: a 2px ring plus a 2px offset stays inside the 6px mobile gap. */
.booking-region .booking-day:focus-visible { outline-offset: 2px; }
.booking-slots { display: grid; align-content: start; gap: 0.625rem; margin-top: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 6px; }
.booking-slots:empty { display: none; }
.booking-region .booking-slots button { border: 1px solid #92b3fa; color: var(--booking-blue); min-height: 54px; font-size: 0.8125rem; line-height: 1.5; font-weight: 600; padding: 0.625rem; }
.booking-region .booking-slots button:hover:not(:disabled) { background: var(--booking-pale); }
.booking-region .booking-slots button[aria-pressed="true"],
.booking-region .booking-slots button[aria-pressed="true"]:hover:not(:disabled) { background: var(--booking-blue); border-color: var(--booking-blue); color: #fff; }
.booking-region .booking-slots button:disabled { color: #626262; background: #f2f2f2; border-color: #ccc; cursor: not-allowed; opacity: 1; }
/* FAHDS-187: the loading skeleton. Static markup before #booking-calendar, so it
   paints with the HTML, before any script runs; aria-hidden and nothing focusable
   inside, so #booking-status's "Loading available times..." stays the only
   announcement. It is built from the calendar's own layout classes
   (.booking-month-nav, .booking-weekdays with the same text, .booking-days) and
   shares the tile-sizing rules above, so its box is the calendar's box. Neutral
   grey placeholders (owner), derived from --color-border; the first
   background-color is the fallback where color-mix is unsupported. */
.booking-scheduler { position: relative; }
.booking-skeleton { position: relative; overflow: hidden; }
/* One sweep across the whole skeleton, transform only. Over the white gaps the band
   is invisible; over the grey blocks it reads as a left-to-right sheen. At rest
   (reduced motion) it sits off to the left, clipped by overflow: hidden. */
.booking-skeleton::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--color-bg) 65%, transparent) 50%, transparent 100%);
  animation: booking-skeleton-shimmer 1.6s ease-in-out infinite;
}
@keyframes booking-skeleton-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.booking-region .booking-skeleton-heading,
.booking-region .booking-skeleton-days > span {
  background-color: var(--color-border);
  background-color: color-mix(in srgb, var(--color-border) 55%, var(--color-bg));
}
.booking-region .booking-skeleton-heading { display: block; width: 7.5rem; height: 0.9375rem; border-radius: 6px; }
/* The box matches the arrow buttons (36 x 40, 44 tall at <=700px - see the mobile
   query); only a small dot inside it is painted, so it does not read as two pills. */
.booking-region .booking-month-arrows .booking-skeleton-arrow {
  display: block; width: 36px; min-height: 40px;
  background-image: radial-gradient(circle, var(--color-border) 7px, transparent 7.5px);
  background-image: radial-gradient(circle, color-mix(in srgb, var(--color-border) 55%, var(--color-bg)) 7px, transparent 7.5px);
}
/* 42 tiles in the markup; data-weeks (set by load() from weeksInMonth()) shows 4, 5
   or 6 rows, matching the grid calendarDays() will render. */
.booking-skeleton[data-weeks="4"] .booking-skeleton-days > span:nth-child(n+29),
.booking-skeleton[data-weeks="5"] .booking-skeleton-days > span:nth-child(n+36) { display: none; }
/* The first reveal's crossfade. Out of flow in the same frame #booking-content
   enters it, but top stays auto, so it keeps its static position - exactly where it
   was, over the calendar's footprint. Paint order does not matter: both layers fade
   over the same 200ms. `forwards` holds opacity 0, so even if js/booking.mjs's
   timeout fallback runs late, no visible skeleton is left over the calendar. */
.booking-skeleton.booking-skeleton-exit { position: absolute; inset-inline: 0; pointer-events: none; animation: booking-skeleton-out 200ms ease-out forwards; }
@keyframes booking-skeleton-out { to { opacity: 0; } }
/* Safety nets that need no script (plan review P3): a fresh book.html running a
   stale cached booking.mjs never hides the skeleton, so hide it once the calendar
   is showing (except during the exit fade), and whenever the Retry row is. */
.booking-scheduler:has(#booking-content:not([hidden])) .booking-skeleton:not(.booking-skeleton-exit),
.booking-scheduler:has(.booking-refresh-row:not([hidden])) .booking-skeleton { display: none; }
@media (scripting: none) { .booking-region .booking-skeleton { display: none; } }
#booking-slot-hint { margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--color-text-light); }
/* Empty whenever a date is chosen (FAHDS-185); it must then take no space at all. */
#booking-slot-hint:empty { margin: 0; }
/* The compact timezone disclosure stays usable during loading and errors. */
.booking-timezone-control { margin-top: 1.5rem; font-size: 0.8125rem; }
.booking-timezone-control summary { cursor: pointer; width: fit-content; max-width: 100%; overflow-wrap: anywhere; border-radius: 3px; padding: 0.4rem 0; }
#booking-timezone-current { margin-left: 0.4rem; font-weight: 600; }
.booking-timezone-editor { max-width: 440px; padding: 0.75rem 0; }
.booking-timezone-control label { display: block; margin-bottom: 0.4rem; }
/* FAHDS-183: a combobox with its listbox popup directly below the input. The row
   is the positioning context; the list overlays what follows instead of pushing it. */
.booking-timezone-row { position: relative; }
.booking-timezone-row input { box-sizing: border-box; display: block; min-width: 0; width: 100%; padding: 0.6rem; border: 1px solid var(--color-text-light); border-radius: 4px; font: inherit; }
#booking-timezone-listbox { position: absolute; z-index: 2; top: calc(100% + 2px); left: 0; right: 0; box-sizing: border-box; max-height: 16rem; overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 0.25rem 0; list-style: none; background: var(--color-bg); color: var(--color-text); border: 1px solid var(--color-border); border-radius: 6px; box-shadow: 0 6px 20px rgb(0 0 0 / 12%); }
/* Options toggle `hidden` as the filter runs, and the list itself opens and closes by
   it. Never give either a display value without this rule beside it. */
#booking-timezone-listbox[hidden], #booking-timezone-listbox [hidden] { display: none; }
#booking-timezone-listbox [role="option"] { padding: 0.45rem 0.6rem; cursor: pointer; overflow-wrap: anywhere; }
#booking-timezone-listbox [role="option"]:hover { background: var(--booking-pale); }
#booking-timezone-listbox [role="option"][aria-selected="true"] { background: var(--booking-pale); color: var(--booking-blue); box-shadow: inset 3px 0 0 var(--booking-blue); }
#booking-timezone-listbox [role="option"][data-current] { font-weight: 600; }
#booking-timezone-listbox .booking-timezone-empty,
#booking-timezone-listbox .booking-timezone-empty:hover { cursor: default; background: none; color: var(--color-text-light); }
/* FAHDS-185: where the zone came from. The zone itself is in the summary above;
   this is the half worth keeping, and it belongs beside the control that changes
   it. It replaces the deleted #booking-zone line in the calendar footer. */
.booking-timezone-source { margin: 0 0 0.75rem; color: var(--color-text-light); overflow-wrap: anywhere; }
#booking-timezone-help, #booking-timezone-error { margin-top: 0.5rem; font-size: 0.8125rem; overflow-wrap: anywhere; }
#booking-timezone-error { color: #a32121; }
#booking-timezone-error:empty { margin: 0; }
/* FAHDS-185: the footer block carries no chrome of its own any more (owner:
   "remove this from the bottom"). The divider belongs to whichever child is
   actually visible, so an idle calendar ends at the timezone disclosure with no
   rule floating above empty space. #booking-status is empty at rest and only
   carries genuine messages now - errors, availability failures, timezone changes,
   the email escapes - each of which brings the rule back with it. */
.booking-utilities { font-size: 0.8125rem; color: var(--color-text-light); }
#booking-status { color: var(--color-text); margin: 0; }
#booking-status:not(:empty) { border-top: 1px solid var(--color-border); margin-top: 1rem; padding-top: 1rem; }
.booking-refresh-row:not([hidden]) { border-top: 1px solid var(--color-border); margin-top: 1rem; padding-top: 1rem; }
/* Both visible: one rule between them, not two. They are adjacent siblings. */
#booking-status:not(:empty) + .booking-refresh-row:not([hidden]) { border-top: 0; margin-top: 0.25rem; padding-top: 0; }
.booking-refresh-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin: 0.25rem 0; }
/* The row's display:flex would override the hidden attribute; FAHDS-182 hides it except for Retry. */
.booking-refresh-row[hidden] { display: none; }
.booking-region #booking-refresh { color: var(--booking-blue); border: 0; padding: 0; min-height: 36px; font-size: 0.8125rem; }
#booking-slot-hint, .booking-summary, .booking-slots button { overflow-wrap: anywhere; }
.booking-summary { margin-top: 1.5rem; padding: 1rem; border-left: 3px solid var(--color-link); background: var(--booking-pale); font-size: 0.875rem; }
/* Details and outcomes remain visible independently of availability. */
.booking-form, .booking-result { margin: 0; overflow-wrap: anywhere; }
.booking-form h3, .booking-result h3 { font-size: 1.1rem; }
.booking-result-title { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.booking-result-title h3 { margin: 0; }
/* Success only: the duplicate "A booking already exists" state gets no success mark. */
.booking-result-check { display: none; flex: 0 0 auto; color: #16a34a; }
.booking-result[data-outcome="success"] .booking-result-check { display: block; }
/* A gap between the message and the booked time (owner, FAHDS-184). */
#booking-result-times { margin-top: 1rem; }
/* FAHDS-436: the room actions as a button row. Open is primary (the submit button's
   blue); copy and download are secondary (the region's outlined button). Wraps on
   narrow screens and stacks full width under 480px. */
.booking-result > p + p { margin-top: 0.75rem; }
.booking-result-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem; margin: 1.25rem 0 0; }
.booking-region .booking-action { display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; min-height: 44px; padding: 0.5rem 1rem; border: 1px solid var(--color-border); border-radius: 8px; background: var(--color-bg); color: var(--color-text); font: inherit; font-size: 0.9375rem; font-weight: 600; line-height: 1.25; text-align: center; text-decoration: none; cursor: pointer; }
.booking-region .booking-action:hover { border-color: var(--booking-blue); background: var(--booking-pale); color: var(--color-text); }
.booking-region .booking-action-primary, .booking-region .booking-action-primary:hover { color: #fff; background: var(--booking-blue); border-color: var(--booking-blue); }
.booking-region .booking-action-primary:hover { filter: brightness(0.95); }
.booking-region .booking-action:focus-visible { outline: 2px solid var(--booking-blue); outline-offset: 3px; }
@media (max-width: 480px) {
  .booking-result-actions { flex-direction: column; align-items: stretch; }
  .booking-region .booking-action { width: 100%; }
}
/* FAHDS-199: Back moved into the actions row at the end of the form, so the heading
   is the first child and needs no room above it. */
#booking-form-heading { margin-top: 0; }
.booking-form label { display: block; margin-top: 1rem; margin-bottom: 0.375rem; font-size: 0.875rem; font-weight: 600; color: var(--color-text); }
/* FAHDS-199 (cal.com cue): softer inputs. #8c8c8c is about 3.4:1 on white, lighter
   than the old #666 but still >= 3:1 for the input boundary (WCAG 1.4.11). Hover and
   focus skip [aria-invalid="true"] so the error border always wins. */
.booking-form input, .booking-form textarea, .booking-form select { box-sizing: border-box; display: block; width: 100%; min-width: 0; padding: 0.625rem 0.75rem; border: 1px solid #8c8c8c; border-radius: 8px; background: var(--color-bg); color: var(--color-text); font: inherit; }
.booking-form input:hover:not(:disabled):not([aria-invalid="true"]),
.booking-form select:hover:not(:disabled):not([aria-invalid="true"]),
.booking-form textarea:hover:not(:disabled):not([aria-invalid="true"]) { border-color: var(--color-text-light); }
.booking-form input:focus-visible:not([aria-invalid="true"]),
.booking-form select:focus-visible:not([aria-invalid="true"]),
.booking-form textarea:focus-visible:not([aria-invalid="true"]) { border-color: var(--booking-blue); }
.booking-form textarea { resize: vertical; }
/* Meeting space: same field look as the inputs, with a drawn chevron. */
.booking-form select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2.25rem;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 52%, calc(100% - 0.8rem) 52%;
  background-size: 0.3rem 0.3rem;
  background-repeat: no-repeat;
}
.booking-field-error { font-size: 0.8125rem; margin-top: 0.35rem; }
.booking-field-error { color: #a32121; }
.booking-field-error:empty, #booking-form-status:empty { margin: 0; }
.booking-form [aria-invalid="true"] { border-color: #a32121; }
.booking-form input:disabled, .booking-form textarea:disabled { opacity: 0.75; }
/* Turnstile widget: spacing only. It is rendered lazily on first entry to the
   details stage, so this box is empty until then and must not reserve space. */
.booking-turnstile:not(:empty) { margin-top: 1rem; }
/* FAHDS-57: the escape shown when no token can be minted. Hidden until then. */
.booking-fallback:not([hidden]) { margin-top: 1rem; }
/* FAHDS-199 (cal.com cue): a text-style Back beside a solid rounded primary, right-
   aligned at the end of the form. The row supplies the spacing, so #booking-submit has
   no margin of its own. */
.booking-form-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.5rem; margin-top: 1.5rem; }
.booking-region #booking-details-back { border: 0; background: transparent; color: var(--color-text); border-radius: 8px; padding: 0.5rem 0.875rem; }
.booking-region #booking-details-back:hover:not(:disabled) { background: #f2f2f2; }
.booking-region #booking-details-back:disabled { color: var(--color-text-light); cursor: default; }
.booking-region #booking-submit { color: #fff; background: var(--booking-blue); border-color: var(--booking-blue); border-radius: 8px; padding: 0.5rem 1.25rem; font-weight: 600; }
.booking-region #booking-retry { color: #fff; background: var(--booking-blue); border-color: var(--booking-blue); margin-top: 1rem; }
.booking-region #booking-submit:disabled { color: #555; background: #eee; border-color: #ddd; }
#booking-form-status, .booking-result p { overflow-wrap: anywhere; }
#booking-form-status:not(:empty) { margin-top: 1.5rem; }
.booking-summary p:last-child, .booking-result p:last-child { margin-bottom: 0; }
@media (max-width: 700px) {
  .booking-page { padding-top: 1.5rem; padding-bottom: 3rem; }
  /* Vertical only, as at desktop: the side gutter is .container's 1.5rem. */
  .booking-identity, .booking-scheduler { padding: 16px 0; }
  .booking-region #booking-refresh, .booking-region .booking-month-arrows button,
  .booking-region .booking-month-arrows .booking-skeleton-arrow { min-height: 44px; }
  /* FAHDS-185: the stacked flow. The panes stop sharing one grid area, so the
     slot list lays out UNDER a calendar that js/booking.mjs keeps visible and
     interactive (it clears inert/aria-hidden at this width - CSS cannot). Hidden
     panes are display:none, so auto-placement puts the calendar in row 1 and the
     times panel in row 2 with nothing else in play. */
  .booking-stages > * { grid-area: auto; }
  .booking-stages[data-stage="times"] > #booking-underlay { visibility: visible; }
  .booking-stages[data-stage="times"] > .booking-times-panel { margin-top: 1.5rem; }
  /* The calendar did not go anywhere - only the slot list is new, so only the
     slot list moves. A downward reveal reads as "expanded into place" under the
     day just tapped; a horizontal slide would be nonsense here. Tapping a SECOND
     day does not change data-stage, so js/booking.mjs replays this with
     panel.animate() - see replaySlotsReveal(). */
  .booking-stages[data-stage="times"] { animation: none; }
  .booking-stages[data-stage="times"] > .booking-times-panel { animation: booking-slots-reveal 220ms ease-out; }
  /* The slot list carries its own day heading here; two renderings of the same
     date, one screen apart, is the duplication this ticket exists to remove. Once
     a time is chosen the stage is `details`, the slot list is gone and the header
     date is the only rendering - and it then carries the time too. */
  :root[data-booking-stage="times"] .booking-selected-date { display: none; }
  .booking-slots-day { display: block; font-size: 1.25rem; line-height: 1.2; letter-spacing: -0.02em; }
  .booking-slots-day .booking-slots-weekday { font-weight: 650; color: var(--color-text); }
  .booking-slots-day .booking-slots-date { font-weight: 400; color: var(--color-text-light); }
  /* FAHDS-199: tiles fill the track (the base rule's width and 78px cap) with a 6px
     gap both ways. At a 400px viewport the column is 352px, so tracks are
     (352 - 36) / 7 = 45.1px square tiles. At 390px tracks are 43.7px and min-height
     wins, giving a 43.7x44 tile: the >=44px touch target still beats the shape (plan
     review F5). Between roughly 630 and 700px the 78px cap binds and the column gap
     grows past 6px - accepted, so tablets never draw squares bigger than desktop's. */
  .booking-weekdays, .booking-days { gap: 6px; }
  .booking-region .booking-day,
  .booking-region .booking-skeleton-days > span { min-height: 44px; }
  .booking-region .booking-day { font-size: 1.125rem; }
  /* One slot per row at every mobile width, not only below 420px (owner). */
  .booking-slots { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
  .booking-region .booking-slots button { border-radius: 10px; min-height: 52px; font-size: 0.875rem; }
}
@keyframes booking-slots-reveal { from { opacity: 0; transform: translateY(-6px); } }
/* Must stay after every booking rule that sets an animation - in particular after
   the max-width: 700px query. Deliberately over-specific: the mobile slot-reveal rule is
   (0,3,0) and media queries contribute no specificity, so a lower-specificity
   override here would silently lose and animate anyway (plan review F1). The
   script-driven replay in replaySlotsReveal() is NOT covered by CSS and gates
   itself on the same media query. FAHDS-187: the skeleton's shimmer (on ::after)
   and its exit fade are covered here too; js/booking.mjs hides it without a fade
   under reduced motion, since a killed animation never fires animationend. */
@media (prefers-reduced-motion: reduce) {
  .booking-region .booking-stages[data-stage],
  .booking-region .booking-stages[data-stage] > *,
  .booking-region #booking-content,
  .booking-region .booking-skeleton,
  .booking-region .booking-skeleton::after,
  .log-region .log-skeleton::after { animation: none !important; }
  /* FAHDS-195: the /log day swap dims without a fade. */
  .log-region .log-day-nav,
  .log-region .log-day-title,
  .log-region .log-overview,
  .log-region .log-category-summary,
  .log-region .log-changes { transition: none !important; }
  /* FAHDS-253: the archive page swap replaces the list without a fade. */
  .log-region .log-post-list { transition: none !important; }
  .log-region .log-post-list.is-fading { opacity: 1 !important; }
  /* FAHDS-197: keep site-wide transitions and animation off under /pomo. FAHDS-218 restores only
     the toast's stationary opacity fade below; the elapsed timers remain text only. */
  .pomo-page *, .pomo-page *::before, .pomo-page *::after { transition: none !important; animation: none !important; }
  .pomo-page .pomo-calendar[open] { transform: none !important; animation: none !important; }
  .pomo-page .pomo-toast { transform: none !important; animation: pomo-toast-fade 3.8s ease-out both !important; }
}

/* Posts / Writing */
.posts {
  padding-bottom: 4rem;
}

.post-card {
  margin-bottom: 3rem;
}

.post-date {
  font-size: 0.85rem;
  color: var(--color-text-light);
  display: block;
  margin-bottom: 0.5rem;
}

.post-title {
  font-family: var(--font-sans);
  font-size: 1.25rem;
  font-weight: 500;
  margin-bottom: 0.5rem;
  line-height: 1.4;
}

.post-title a {
  color: var(--color-text);
  text-decoration: none;
}

.post-title a:hover {
  color: var(--color-link);
  text-decoration: none;
}

.post-excerpt {
  color: var(--color-text-light);
  font-size: 1rem;
  line-height: 1.6;
}

/* Single post page */
.post-header {
  padding: 3rem 0 2rem;
}

.post-header h1 {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.post-content {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1.1rem;
  line-height: 1.8;
  padding-bottom: 3rem;
}

.post-content h2 {
  font-family: var(--font-sans);
  font-size: 1.5rem;
  margin: 2rem 0 1rem;
}

.post-content p {
  margin-bottom: 1.5rem;
}

.post-content ul,
.post-content ol {
  margin-bottom: 1.5rem;
  padding-left: 1.5rem;
}

.post-content blockquote {
  border-left: 3px solid var(--color-text);
  margin: 1.5rem 0;
  padding-left: 1rem;
  color: var(--color-text-light);
  font-style: italic;
}

.post-content code {
  background: #f5f5f5;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-size: 0.9em;
}

.post-content pre {
  background: #1e1e1e;
  color: #d4d4d4;
  padding: 1rem;
  border-radius: 8px;
  overflow-x: auto;
  margin-bottom: 1.5rem;
}

.post-content pre code {
  background: none;
  padding: 0;
}

.post-content table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}

.post-content th,
.post-content td {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  text-align: left;
}

.post-content th {
  background: #f5f5f5;
  font-weight: 600;
}

/* Projects page */
.projects-list {
  padding-bottom: 1.5rem;
}

.projects-list h2 {
  margin-bottom: 1rem;
}

.project-item {
  margin-bottom: 1.5rem;
}

.project-item-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.25rem;
}

.project-thumb {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
}

.project-thumb.contain {
  object-fit: contain;
}

.project-item h3 {
  font-size: 1.1rem;
  font-weight: 500;
  margin-bottom: 0;
}

.project-item h3 a {
  color: var(--color-text);
  text-decoration: none;
}

.project-item h3 a:hover {
  color: var(--color-link);
  text-decoration: none;
}

.project-item p {
  color: var(--color-text-light);
  font-size: 1rem;
  line-height: 1.6;
  margin-bottom: 0.25rem;
}

.project-item .project-tech {
  color: var(--color-text-light);
  font-size: 0.9rem;
}

/* Series styles */
.series-section {
  margin-bottom: 2.5rem;
}

.series-card {
  display: block;
  color: var(--color-text);
}

.series-card:hover {
  color: var(--color-text);
}

.series-card-content h2 {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 500;
  margin-bottom: 0.5rem;
}

.series-card-content p {
  color: var(--color-text-light);
  font-size: 1rem;
  line-height: 1.6;
  margin-bottom: 0.25rem;
}

.series-count {
  font-size: 0.9rem;
  color: var(--color-text-light);
}

.series-arrow {
  display: none;
}

/* Series index page */
.series-header {
  padding: 3rem 0 2rem;
}

.series-header h1 {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.series-description {
  color: var(--color-text-light);
  font-size: 1.1rem;
  margin-bottom: 0.5rem;
}

.series-meta {
  color: var(--color-text-light);
  font-size: 0.9rem;
}

.series-list {
  padding-bottom: 3rem;
}

.series-list ol {
  list-style: none;
}

.series-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--color-border);
}

.series-item-number {
  color: var(--color-text-light);
  font-size: 0.9rem;
  min-width: 2rem;
  text-align: right;
}

.series-item a {
  flex: 1;
  color: var(--color-text);
}

.series-item a:hover {
  color: var(--color-link);
}

.series-item time {
  color: var(--color-text-light);
  font-size: 0.85rem;
}

/* Series navigation (on post pages) */
.series-nav {
  margin: 1.5rem 0;
}

.back-link {
  color: var(--color-text-light);
  font-size: 0.9rem;
}

.back-link:hover {
  color: var(--color-text);
}

/* Footer */
.site-footer {
  margin-top: auto;
  border-top: 1px solid var(--color-border);
  padding: 2rem 0;
  text-align: center;
}

.site-footer p {
  color: var(--color-text-light);
  font-size: 0.85rem;
}

.social-icons {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

/* the now-playing widget shares this row but must shed the icon-button styling */
.social-icons a.now-playing {
  width: auto;
  height: auto;
  padding: 0;
  border-radius: 0;
  background: none;
  margin-left: 0.4rem;
}

.social-icons a.now-playing:hover {
  background: none;
}

.social-icons a.now-playing.now-playing-hidden {
  display: none;
}

.social-icons a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  color: var(--color-text-light);
  background: #f5f5f5;
  text-decoration: none;
  transition: all 0.2s ease;
}

.social-icons a:hover {
  background: #333;
  color: #fff;
  text-decoration: none;
}

/* Responsive */
@media (max-width: 600px) {
  .intro h1 {
    font-size: 2rem;
  }

  .intro {
    padding: 0rem 0 4rem;
  }

  .nav-links {
    gap: 1rem;
  }

  .post-title {
    font-size: 1.15rem;
  }

  .page-header h1 {
    font-size: 2rem;
  }
}

/* ─── Spotify now-playing (inline, subtle) ─── */
.intro .now-playing,
.now-playing {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  color: var(--color-text-light);
  text-decoration: none;
  /* hidden until a track arrives */
  opacity: 0;
  transition: opacity 0.3s ease;
}

.intro .now-playing:hover,
.now-playing:hover {
  background: none;
  text-decoration: none;
}

/* state classes are .intro-scoped so they out-specify the reset above */
.intro .now-playing-hidden,
.now-playing-hidden {
  display: none;
}

.intro .now-playing-visible,
.now-playing-visible {
  opacity: 0.85;
}

.intro .now-playing:hover,
.now-playing:hover {
  opacity: 1;
}

/* "Listening to Spotify" label + green mark, then a colon */
.now-playing-label {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  font-size: 0.76rem;
  color: var(--color-text-light);
  white-space: nowrap;
}

.now-playing-label::after {
  content: ":";
}

.now-playing-spotify {
  width: 0.95em;
  height: 0.95em;
  fill: #1db954;
  flex-shrink: 0;
}

.now-playing-art {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  animation: now-playing-spin 5s linear infinite;
}

/* pause the spin when the track is paused */
.now-playing-paused .now-playing-art {
  animation-play-state: paused;
}

@keyframes now-playing-spin {
  to { transform: rotate(360deg); }
}

.now-playing-track {
  white-space: nowrap;
  font-size: 0.76rem;
  color: var(--color-text-light);
}

.now-playing-title {
  color: var(--color-text);
  font-weight: 600;
}

.now-playing-time {
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-light);
  opacity: 0.7;
  white-space: nowrap;
}

/* Mobile: wrap the widget onto its own line under the icons and
   let the track title truncate so the row never overflows the viewport. */
@media (max-width: 600px) {
  .social-icons {
    flex-wrap: wrap;
  }

  .social-icons a.now-playing {
    flex: 1 1 100%;
    margin-left: 0;
    margin-top: 0.75rem;
    min-width: 0;
  }

  .now-playing-track {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Very narrow: drop the timestamp to keep artist – song readable. */
@media (max-width: 380px) {
  .now-playing-time {
    display: none;
  }
}

/* Keep contextual booking contact links distinguishable within prose. */
.booking-region a[href^="mailto:"] { text-decoration: underline; }

/* FAHDS-185 emptied this wrapper of everything but the copy fallback - the help
   line that used to explain the Copy link button is gone, and with it the two
   rules that styled it - so the spacing moved onto the fallback itself: an empty
   wrapper now contributes nothing. */
#booking-copy-fallback { margin-top: 0.75rem; }
#booking-copy-fallback label { display: block; font-size: 0.8125rem; }
#booking-copy-url { box-sizing: border-box; width: 100%; min-width: 0; font: inherit; }

/* FAHDS-195: /log
   One day per view, filled by js/log.mjs. No card, no new colours: the existing tokens only.
   The only animation is the loading skeleton's sheen (killed, with the day-swap dim, by the
   reduced-motion block above - kept there because booking's tests pin that block as the last
   reduced-motion query in this file). */
.log-page { padding-top: 2.5rem; padding-bottom: 4rem; }
.log-intro { display: flex; flex-direction: column; gap: 1.25rem; margin-bottom: 2.5rem; }
.log-intro p { color: var(--color-text); line-height: 1.6; }
.log-posts { margin-bottom: 2.5rem; }
.log-posts-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 1rem; }
.log-posts-header .log-home-heading { margin-bottom: 0; }
.log-post-filter { display: inline-flex; padding: 3px; border: 1px solid var(--color-border); border-radius: 8px; gap: 2px; }
.log-post-filter button { min-height: 36px; padding: 0.375rem 0.75rem; border: 0; border-radius: 5px; background: transparent; color: var(--color-text-light); font: inherit; font-size: 0.8125rem; cursor: pointer; }
.log-post-filter button[aria-pressed="true"] { background: var(--color-border); color: var(--color-text); font-weight: 500; }
.log-post-filter button:focus-visible { outline: 2px solid var(--color-text); outline-offset: 2px; }
.log-heatmap { margin-bottom: 4rem; }
/* (0,2,0): beats every display rule below, so `hidden` always hides. */
.log-region [hidden] { display: none; }
.log-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Heading centred between the two arrows. */
.log-day-nav { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 0.5rem; margin-bottom: 1.5rem; }
.log-day-nav h1 {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; line-height: 1.25;
  letter-spacing: -0.01em; text-align: center; color: var(--color-text);
}
.log-day-nav h1:focus { outline: none; }
.log-day-nav h1:focus-visible { outline: 2px solid var(--color-link); outline-offset: 4px; border-radius: 4px; }
/* 44 x 44 at every width: comfortably a touch target, and the arrows never move. */
.log-arrow {
  display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 8px; font-size: 1.75rem; line-height: 1; color: var(--color-text); text-decoration: none;
  user-select: none;
}
.log-arrow[href]:hover { color: var(--color-text-light); background: #f5f5f5; text-decoration: none; }
.log-arrow:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.log-arrow:hover { text-decoration: none; }
.log-arrow[aria-disabled="true"] { color: var(--color-border); cursor: default; background: transparent; }
/* FAHDS-231: the saved day title follows the date navigation without becoming another heading. */
.log-day-title {
  margin: 2rem 0 1.25rem; font-family: var(--font-display); font-size: 1.6rem;
  font-weight: 700; line-height: 1.25; letter-spacing: 0; text-align: left; color: var(--color-text);
  overflow-wrap: anywhere;
}
/* Picture of the day on top, summary underneath (owner); without a photo there is no slot. */
.log-overview { display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; margin-bottom: 2rem; }
/* The flex gap already spaces the heading from the photo. */
.log-overview > .log-overview-title { margin-bottom: -0.25rem; }
.log-summary { flex: 1; min-width: 0; white-space: pre-line; overflow-wrap: anywhere; color: var(--color-text); }
.log-category-summary { margin: 2rem 0; }
.log-category-summary ul { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin: 0; padding: 0; list-style: none; }
.log-category-summary li { display: inline-flex; align-items: center; gap: 0.45rem; color: var(--color-text); }
.log-category-summary li::before {
  content: ""; flex: none; width: 0.55rem; height: 0.55rem; border: 0;
  border-radius: 50%; background: var(--cat-popup, var(--cat-dot));
}
.log-photo {
  appearance: none; display: block; flex-shrink: 0; margin: 0; padding: 0; border: 0;
  border-radius: 8px; background: transparent; color: inherit; font: inherit; line-height: 0;
  text-align: inherit; cursor: zoom-in; touch-action: manipulation;
}
.log-photo img { display: block; height: auto; border-radius: 8px; background: #f5f5f5; }
.log-captioned-photo { cursor: default; line-height: normal; }
.log-captioned-photo > .log-photo-trigger { width: 100%; }
.log-photo-caption { max-width: 100%; margin: 0.4rem auto 0; color: var(--color-text-light); font-size: 0.82rem; font-style: italic; line-height: 1.35; text-align: center; overflow-wrap: anywhere; }
.log-photo-tile { min-width: 0; margin: 0; }
.log-photo-tile .log-photo-caption { font-size: 0.72rem; }
.log-photo:hover img { opacity: 0.96; }
.log-day-photo { align-self: stretch; }
.log-day-photo img { width: 100%; height: auto; margin: 0 auto; }
.log-entry-photo { margin-top: 0.5rem; width: fit-content; }
.log-entry-photo img { width: 160px; }
.log-photo:focus-visible, .log-photo-grid-item:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.log-photo-grid { display: grid; gap: 0.25rem; width: 160px; line-height: 0; }
.log-subtask-photo.log-photo-grid { width: 140px; }
.log-photo-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.log-photo-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.log-photo-grid .log-photo-grid-item {
  appearance: none; display: block; min-width: 0; margin: 0; padding: 0; border: 0; border-radius: 5px;
  background: transparent; cursor: zoom-in; overflow: hidden;
}
.log-photo-grid .log-photo-grid-item img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 5px; }
.log-photo-grid .log-photo-tile .log-photo-grid-item { width: 100%; }
.log-lightbox-caption { position: absolute; z-index: 2; right: 1rem; bottom: max(1rem, env(safe-area-inset-bottom)); left: 1rem; max-width: 42rem; margin: 0 auto; padding: 0.4rem 0.65rem; border-radius: 4px; background: rgb(0 0 0 / 65%); color: #fff; font-size: 0.875rem; font-style: italic; text-align: center; overflow-wrap: anywhere; }
.log-lightbox {
  box-sizing: border-box; position: fixed; inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
  margin: 0; padding: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right))
    max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
  border: 0; background: transparent; color: #fff; overflow: hidden;
}
.log-lightbox::backdrop { background: rgb(0 0 0 / 0.88); }
.log-lightbox-frame { display: grid; place-items: center; width: 100%; height: 100%; }
.log-lightbox-image, .log-lightbox-status { grid-area: 1 / 1; }
.log-lightbox-image {
  display: block; visibility: hidden; min-width: 0; min-height: 0; width: auto; height: auto;
  max-width: 100%; max-height: 100%; object-fit: contain;
}
.log-lightbox-image.is-ready { visibility: visible; }
.log-lightbox-status {
  max-width: min(28rem, calc(100vw - 4rem)); margin: 0; padding: 0.75rem 1rem;
  color: #fff; background: rgb(0 0 0 / 0.72); text-align: center; line-height: 1.4;
}
.log-lightbox-close {
  appearance: none; position: fixed; z-index: 1;
  top: max(1rem, env(safe-area-inset-top)); right: max(1rem, env(safe-area-inset-right));
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-width: 44px; min-height: 44px; padding: 0; border: 1px solid rgb(255 255 255 / 0.5);
  border-radius: 50%; background: rgb(0 0 0 / 0.72); color: #fff; font: inherit; font-size: 2rem;
  font-weight: 300; line-height: 1; cursor: pointer; touch-action: manipulation;
}
.log-lightbox-close:hover { background: #000; }
.log-lightbox-close:focus-visible, .log-lightbox-previous:focus-visible, .log-lightbox-next:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.log-lightbox-counter {
  position: fixed; left: 50%; bottom: max(1rem, env(safe-area-inset-bottom)); transform: translateX(-50%);
  margin: 0; padding: 0.35rem 0.65rem; border-radius: 999px; background: rgb(0 0 0 / 0.72); color: #fff;
}
.log-lightbox-previous, .log-lightbox-next {
  appearance: none; position: fixed; top: 50%; z-index: 1; width: 48px; height: 56px; margin-top: -28px;
  border: 1px solid rgb(255 255 255 / 0.5); border-radius: 999px; background: rgb(0 0 0 / 0.72);
  color: #fff; font: inherit; font-size: 2rem; cursor: pointer;
}
.log-lightbox-previous { left: max(1rem, env(safe-area-inset-left)); }
.log-lightbox-next { right: max(1rem, env(safe-area-inset-right)); }
.log-lightbox-previous:hover, .log-lightbox-next:hover { background: #000; }
.log-lightbox-open, .log-lightbox-open body { overscroll-behavior: none; }
.log-status { margin: 0; color: var(--color-text-light); }
.log-status:focus { outline: none; }
.log-message { display: block; margin-bottom: 1rem; overflow-wrap: anywhere; }
.log-retry, .log-more {
  font: inherit; font-size: 0.95rem; color: var(--color-text); background: transparent;
  border: 1px solid var(--color-border); border-radius: 8px; padding: 0.4rem 1rem; cursor: pointer;
}
.log-retry:hover, .log-more:hover { background: #f5f5f5; }
.log-retry:focus-visible, .log-more:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.log-more:disabled { opacity: 0.6; cursor: default; }
/* The navigation busy state: the current day stays, dimmed, until the next one arrives. */
.log-region .log-day-nav, .log-region .log-day-title, .log-region .log-overview, .log-region .log-category-summary, .log-region .log-changes { transition: opacity 150ms ease-out; }
.log-region[aria-busy="true"] .log-day-title,
.log-region[aria-busy="true"] .log-overview,
.log-region[aria-busy="true"] .log-category-summary,
.log-region[aria-busy="true"] .log-changes { opacity: 0.55; }
.log-post-list[aria-busy="true"] { opacity: 0.55; }
/* Change Log: a vertical timeline with dotted connectors. */
.log-changes h2, .log-category-summary h2, .log-overview-title, .log-home-heading, .log-changes-title, .log-heatmap-title {
  font-size: 0.8125rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-text-light); margin-bottom: 1rem;
}
.log-timeline { list-style: none; --log-rail: 1.75rem; }
/* Dot rail on the far left; the time, title, description, and optional gallery flow vertically.
   Galleries are always the final content for their parent or nested activity. */
.log-entry {
  position: relative; display: grid;
  grid-template-columns: var(--log-rail) auto minmax(0, 1fr);
  align-items: start; padding-bottom: 2.5rem;
}
.log-entry:last-child { padding-bottom: 0; }
.log-entry > * { grid-column: 2 / 4; }
.log-entry > .log-time { grid-row: 1; line-height: 1.4; }
.log-entry > .log-entry-title { grid-row: 2; margin-top: 0.3rem; }
.log-entry > .log-desc { grid-row: 3; }
.log-entry:has(> .log-entry-photo) > .log-entry-photo { grid-column: 2 / 4; grid-row: 4; }
/* The dot sits on the first line; the connector runs from under it to the next dot. */
.log-entry::before {
  /* Centred on the time's line box: 0.9rem text at line-height 1.4, minus the 14px dot. */
  content: ""; position: absolute; left: 0; top: calc((0.9rem * 1.4 - 14px) / 2);
  width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--color-text-light); background: var(--color-bg);
}
.log-entry::after {
  content: ""; position: absolute; left: 6px; top: calc((0.9rem * 1.4 - 14px) / 2 + 16px); bottom: 6px; border-left: 2px dotted var(--color-border);
}
.log-entry:last-child::after { display: none; }
.log-time { font-size: 0.9rem; color: var(--color-text-light); font-variant-numeric: tabular-nums; }
.log-time[title] { cursor: help; }
.log-tz { font-size: 0.8em; opacity: 0.75; }
.log-heading-tz { margin-left: 0.25rem; letter-spacing: 0.04em; }
.log-next, .log-prevday { font-size: 0.8em; vertical-align: super; line-height: 0; }
/* The representative category shade fills dated-page dots; the darker outline keeps them legible. */
.log-entry.log-entry-has-cat::before { border: 0; background: var(--cat-popup, var(--cat-dot, var(--color-bg))); }
.log-cat { color: var(--color-text-light); }
.log-entry-title { font-size: 1rem; font-weight: 650; line-height: 1.4; color: var(--color-text); overflow-wrap: anywhere; }
.log-entry-title a, .log-subtask-title a {
  color: var(--color-text);
  background: var(--color-link-highlight);
  border: none;
  border-radius: 4px;
  padding: 0.1em 0.35em;
  text-decoration: none;
  transition: background 0.2s ease;
}
.log-entry-title a:hover, .log-subtask-title a:hover {
  color: var(--color-text);
  background: var(--color-link-highlight-hover);
  text-decoration: none;
}
.log-entry-title a:focus-visible, .log-subtask-title a:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: 2px;
}
.log-subtasks { grid-column: 2 / 4; list-style: none; margin: 0.75rem 0 0; padding: 0 0 0 0.5rem; border-left: 1px solid color-mix(in srgb, var(--color-border) 55%, var(--color-bg)); }
.log-subtask { padding: 0.1rem 0 0.65rem 0.5rem; }
.log-subtask:last-child { padding-bottom: 0.1rem; }
.log-subtask-time { margin: 0; color: var(--color-text-light); font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.log-subtask-title { margin: 0.2rem 0 0; font-size: 0.95rem; line-height: 1.4; overflow-wrap: anywhere; }
.log-subtask-desc { margin: 0.2rem 0 0; color: var(--color-text-light); white-space: pre-line; overflow-wrap: anywhere; }
.log-subtask-photo { margin-top: 0.5rem; width: fit-content; }
.log-subtask-photo img { width: 140px; max-width: 100%; }
.log-desc { white-space: pre-line; overflow-wrap: anywhere; color: var(--color-text-light); font-size: 1rem; margin-top: 0.2rem; }
/* The first-load skeleton (FAHDS-187's pattern): static, inert, gone without scripting. */
.log-skeleton { position: relative; overflow: hidden; }
.log-skeleton::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--color-bg) 65%, transparent) 50%, transparent 100%);
  animation: log-skeleton-shimmer 1.6s ease-in-out infinite;
}
@keyframes log-skeleton-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.log-skeleton span {
  display: block; border-radius: 6px;
  background-color: var(--color-border);
  background-color: color-mix(in srgb, var(--color-border) 55%, var(--color-bg));
}
.log-skeleton .log-skeleton-heading { width: 16rem; max-width: 70%; height: 1.5rem; margin: 0.6rem auto 2.1rem; }
.log-skeleton-overview { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; }
.log-skeleton .log-skeleton-photo { width: 100%; aspect-ratio: 4 / 3; border-radius: 8px; }
.log-skeleton-lines { flex: 1; display: flex; flex-direction: column; gap: 0.7rem; padding-top: 0.3rem; }
.log-skeleton-lines span { height: 0.9rem; }
.log-skeleton-lines span:last-child { width: 60%; }
.log-skeleton-row { padding-left: 1.75rem; margin-bottom: 1.75rem; display: flex; flex-direction: column; gap: 0.5rem; }
.log-skeleton-row span:first-child { width: 7rem; height: 0.8rem; }
.log-skeleton-row span:last-child { width: 12rem; height: 1rem; }
.log-post-list { display: flex; flex-direction: column; gap: 1.5rem; margin: 0; padding: 0; list-style: none; }
.log-post-item { display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; column-gap: 1rem; min-width: 0; }
.log-post-copy { min-width: 0; }
.log-post-thumb, .log-post-tile { box-sizing: border-box; display: block; width: 56px; height: 56px; border-radius: 5px; box-shadow: 0 2px 8px rgba(31, 38, 47, 0.14); }
.log-post-tile { box-shadow: none; }
.log-post-thumb { overflow: hidden; background: var(--cat-empty); }
.log-post-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.log-post-tile { display: block; padding: 0; border: 0; background: transparent; cursor: pointer; }
.log-post-thumb:focus-visible, .log-post-tile:focus-visible { outline: 2px solid var(--color-link); outline-offset: 3px; }
.log-post-tile-cell { display: block; width: 100%; height: 100%; border-radius: 5px; background: var(--cat-empty); }
.log-post-tile-cell.cat-work { background: var(--cat-work-base); }
.log-post-tile-cell.cat-study { background: var(--cat-study-3); }
.log-post-tile-cell.cat-exercise { background: var(--cat-exercise-tile); }
.log-post-tile-cell.cat-reading { background: var(--cat-reading-3); }
.log-post-tile-cell.cat-social { background: var(--cat-social-3); }
.log-post-tile-cell.cat-entertainment { background: var(--cat-entertainment-base); }
.log-post-tile-cell.cat-work { --tile-color-1: var(--cat-work-1); --tile-color-2: var(--cat-work-2); --tile-color-3: var(--cat-work-3); --tile-color-4: var(--cat-work-4); --tile-color-5: var(--cat-work-5); }
.log-post-tile-cell.cat-study { --tile-color-1: var(--cat-study-1); --tile-color-2: var(--cat-study-2); --tile-color-3: var(--cat-study-3); --tile-color-4: var(--cat-study-4); --tile-color-5: var(--cat-study-5); }
.log-post-tile-cell.cat-exercise { --tile-color-1: var(--cat-exercise-1); --tile-color-2: var(--cat-exercise-2); --tile-color-3: var(--cat-exercise-3); --tile-color-4: var(--cat-exercise-4); --tile-color-5: var(--cat-exercise-5); }
.log-post-tile-cell.cat-reading { --tile-color-1: var(--cat-reading-1); --tile-color-2: var(--cat-reading-2); --tile-color-3: var(--cat-reading-3); --tile-color-4: var(--cat-reading-4); --tile-color-5: var(--cat-reading-5); }
.log-post-tile-cell.cat-social { --tile-color-1: var(--cat-social-1); --tile-color-2: var(--cat-social-2); --tile-color-3: var(--cat-social-3); --tile-color-4: var(--cat-social-4); --tile-color-5: var(--cat-social-5); }
.log-post-tile-cell.cat-entertainment { --tile-color-1: var(--cat-entertainment-1); --tile-color-2: var(--cat-entertainment-2); --tile-color-3: var(--cat-entertainment-3); --tile-color-4: var(--cat-entertainment-4); --tile-color-5: var(--cat-entertainment-5); }
.log-post-tile-cell[data-level="1"] { background: var(--tile-color-1); }
.log-post-tile-cell[data-level="2"] { background: var(--tile-color-2); }
.log-post-tile-cell[data-level="3"] { background: var(--tile-color-3); }
.log-post-tile-cell[data-level="4"] { background: var(--tile-color-4); }
.log-post-tile-cell[data-level="5"] { background: var(--tile-color-5); }
.log-post-date { margin: 0; font-size: 1rem; line-height: 1.35; overflow-wrap: anywhere; }
.log-post-date a { color: var(--color-text); }
.log-post-date a:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.log-post-title { margin: 0.2rem 0 0; color: var(--color-text); font-weight: 600; overflow-wrap: anywhere; }
.log-posts .log-retry, .log-posts .log-more { margin-top: 0.75rem; }
.log-pager { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
.log-post-list { transition: opacity 160ms ease; }
.log-post-list.is-fading { opacity: 0; }
.log-post-skeleton { display: flex; flex-direction: column; gap: 1.5rem; }
.log-post-skeleton-row {
  display: flex; flex-direction: column; gap: 0.3rem;
}
.log-post-skeleton-row > span:first-child { width: min(15rem, 80%); height: 1rem; }
.log-post-skeleton-row > span:last-child { width: min(22rem, 100%); height: 0.8rem; }
.log-region[data-state]:not([data-state="loading"]) .log-skeleton { display: none; }
@media (scripting: none) { .log-region .log-skeleton { display: none; } }
.log-noscript { color: var(--color-text-light); }
@media (max-width: 560px) {
  .log-page { padding-top: 1.5rem; }
  .log-day-nav h1 { font-size: 1.2rem; }
  .log-day-title { margin-top: 1.5rem; font-size: 1.4rem; }
  .log-post-list, .log-post-skeleton { gap: 1.25rem; }
  .log-post-item { grid-template-columns: 48px minmax(0, 1fr); column-gap: 0.75rem; }
  .log-post-thumb, .log-post-tile { width: 48px; height: 48px; }
  .log-day-photo, .log-skeleton .log-skeleton-photo { max-width: 100%; }
  .log-timeline { --log-rail: 1.5rem; }
  .log-entry > .log-time { font-size: 0.8125rem; }
  .log-entry::before { top: calc((0.8125rem * 1.4 - 14px) / 2); }
  .log-entry::after { top: calc((0.8125rem * 1.4 - 14px) / 2 + 16px); }
  .log-entry-photo img { max-width: 100%; }
  /* Too narrow for photo-beside-text: stack time+title, photo, description. */
  .log-entry:has(> .log-entry-photo) > .log-entry-photo { grid-column: 2 / 4; grid-row: 4; }
}

/* FAHDS-207 heat map */
.log-heatmap { --hm-0: var(--cat-empty); --hm-cell: 8px; --hm-gap: 2px; }
.log-heatmap[data-scale="aggregate"] {
  --hm-0: var(--cat-empty); --hm-1: #f4d67b; --hm-2: #f8b56b; --hm-3: #f28c63; --hm-4: #e85e60;
}
.log-heatmap [hidden] { display: none; }
.log-heatmap-date { min-height: 1.4em; margin: 0 0 0.5rem; color: var(--color-text-light); font-size: 0.875rem; }
.log-heatmap-chips { display: flex; flex-wrap: wrap; gap: 0 0.25rem; margin-top: 1rem; }
.log-heatmap-chip {
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
  max-width: 100%; min-height: 44px; padding: 0; border: 0; border-radius: 999px;
  background: transparent; color: var(--color-text); font: inherit; cursor: pointer;
}
.log-heatmap-chip-label {
  box-sizing: border-box; display: inline-flex; align-items: center; gap: 0.3rem; max-width: 100%;
  padding: 0.2rem 0.5rem; border: 1px solid var(--color-border); border-radius: 999px;
  background: var(--color-bg); font-size: 0.8125rem; font-weight: 500; line-height: 1.2; white-space: nowrap;
}
.log-heatmap-chip-label::before { content: ""; box-sizing: border-box; flex: none; width: 0.5rem; height: 0.5rem; border: 1px solid rgba(31, 38, 47, 0.13); border-radius: 50%; background: var(--cat-dot); }
.log-heatmap-chip.cat-work .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip.cat-study .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip.cat-exercise .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip.cat-reading .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip.cat-social .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip.cat-entertainment .log-heatmap-chip-label::before { background: var(--cat-popup); }
.log-heatmap-chip[aria-pressed="true"] .log-heatmap-chip-label { border-color: transparent; background: var(--color-link-highlight); }
.log-heatmap-chip:hover .log-heatmap-chip-label { background: #f5f5f5; }
.log-heatmap-chip[aria-pressed="true"]:hover .log-heatmap-chip-label { background: var(--color-link-highlight-hover); }
.log-heatmap-chip:focus-visible, .log-heatmap-retry:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.log-heatmap-status { margin: 0; color: var(--color-text-light); font-size: 0.875rem; }
.log-heatmap-status:focus { outline: none; }
.log-heatmap-scroll {
  /* Keep absolute screen-reader labels inside the scrolling viewport. */
  position: relative;
  width: 100%; max-width: 100%; min-width: 0; overflow-x: auto;
  contain: inline-size; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
}
.log-heatmap-grid { display: flex; flex-direction: column; width: 100%; min-width: 0; }
.log-heatmap-months, .log-heatmap-row {
  display: grid; grid-template-columns: 1.75rem repeat(53, var(--hm-cell)); column-gap: var(--hm-gap);
}
.log-heatmap-months {
  min-height: 1em; margin-bottom: var(--hm-gap); color: var(--color-text-light);
  font-size: 0.7rem; font-weight: 400;
}
.log-heatmap-month { min-width: 0; overflow: clip; text-align: left; white-space: nowrap; }
.log-heatmap-rows { display: flex; flex-direction: column; gap: var(--hm-gap); }
.log-heatmap-weekday {
  height: var(--hm-cell); overflow: visible; color: var(--color-text-light); font-size: 0.7rem;
  font-weight: 400; line-height: var(--hm-cell); text-align: left; white-space: nowrap;
}
.log-heatmap-cell {
  box-sizing: border-box; width: var(--hm-cell); height: var(--hm-cell); min-width: 0;
  border-radius: 2px; background: var(--hm-0);
}
.log-heatmap-cell[data-level="1"], .log-heatmap-swatch[data-level="1"] { background: var(--hm-1); }
.log-heatmap-cell[data-level="2"], .log-heatmap-swatch[data-level="2"] { background: var(--hm-2); }
.log-heatmap-cell[data-level="3"], .log-heatmap-swatch[data-level="3"] { background: var(--hm-3); }
.log-heatmap-cell[data-level="4"], .log-heatmap-swatch[data-level="4"] { background: var(--hm-4); }
.log-heatmap-cell[data-level="5"], .log-heatmap-swatch[data-level="5"] { background: var(--hm-5); }
.log-heatmap-grid .log-heatmap-void { background: transparent; }
@media (hover: hover) and (pointer: fine) {
  .log-heatmap-cell[data-date]:hover { background: #000; }
  .log-heatmap[data-scale="aggregate"] .log-heatmap-cell[data-date]:hover { outline: 1px solid var(--color-link); outline-offset: 1px; }
}
.log-heatmap-cell[data-date]:focus-visible { background: #000; }
.log-heatmap-cell[data-has-activity="true"] { cursor: pointer; }
.log-heatmap-cell:focus-visible { outline: 2px solid var(--color-link); outline-offset: 1px; }
.log-heatmap-legend { display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; margin: 0.5rem 0 0; padding: 0; list-style: none; font-size: 0.75rem; color: var(--color-text-light); }
.log-heatmap-legend li { display: inline-flex; align-items: center; gap: 0.25rem; }
.log-heatmap-swatch { width: var(--hm-cell); height: var(--hm-cell); border-radius: 2px; background: var(--hm-0); }
.log-heatmap[data-scale="aggregate"] .log-heatmap-legend { justify-content: flex-end; gap: 0.25rem; }
.log-heatmap[data-scale="aggregate"] .log-heatmap-legend-word:first-child { margin-right: 0.125rem; }
.log-heatmap[data-scale="aggregate"] .log-heatmap-legend-word:last-child { margin-left: 0.125rem; }
.log-heatmap-popup {
  position: fixed; z-index: 100; box-sizing: border-box; width: max-content; max-width: calc(100vw - 1rem);
  padding: 0.65rem 0.75rem; border: 1px solid #30363d; border-radius: 6px; background: #161b22;
  color: #f0f6fc; box-shadow: 0 8px 24px rgb(0 0 0 / 0.25); font-size: 0.75rem; line-height: 1.35;
  pointer-events: none;
}
.log-heatmap-popup-date { margin: 0 0 0.45rem; color: #f0f6fc; font-weight: 600; }
.log-heatmap-popup-list { display: grid; gap: 0.25rem; margin: 0; padding: 0; list-style: none; }
.log-heatmap-popup-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem; align-items: center; }
.log-heatmap-popup-name { display: inline-flex; min-width: 0; align-items: center; gap: 0.4rem; }
.log-heatmap-popup-marker { flex: none; width: 0.5rem; height: 0.5rem; border-radius: 2px; background: var(--cat-popup, var(--cat-dot)); }
.log-heatmap-popup-duration { color: #b1bac4; text-align: right; white-space: nowrap; }
.log-heatmap-popup-empty { margin: 0; color: #b1bac4; }
.log-heatmap-retry {
  margin-top: 0.5rem; padding: 0.4rem 1rem; border: 1px solid var(--color-border); border-radius: 8px;
  background: transparent; color: var(--color-text); font: inherit; font-size: 0.95rem; cursor: pointer;
}
.log-heatmap-retry:hover { background: #f5f5f5; }
@media (max-width: 560px) {
  .log-heatmap { --hm-cell: 20px; --hm-gap: 3px; }
}

/* FAHDS-197: /pomo
   The private timer page. Mobile-first for an iPhone: 48px targets, 16px+ inputs (iOS zooms on
   focus below that), safe-area padding for the Home Screen app. Site tokens, plus the --pomo-*
   tokens below so FAHDS-256's dark palette can redefine every colour in one place. */
.pomo-body {
  padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right);
  --pomo-surface: #f5f5f5; --pomo-highlight: #f5f8ff; --pomo-strong: #111; --pomo-input-border: #8c8c8c;
  --pomo-disabled: #b8b8b8; --pomo-tick: #c4c4c4; --pomo-danger: #b42318; --pomo-danger-hover: #912018; --pomo-on-danger: #fff;
}
/* FAHDS-256: dark mode. Follows the system unless <html data-theme> (js/pomo-theme.mjs) says
   otherwise. Only /pomo ever sets data-theme or has .pomo-body, so nothing leaks site-wide. The
   two blocks must stay identical (CSS cannot share one declaration list); test/pomo-theme.test.mjs checks. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):has(.pomo-body) { color-scheme: dark; }
  :root:not([data-theme="light"]) .pomo-body {
    --color-bg: #161616; --color-text: #e8e8e8; --color-text-light: #a3a3a3; --color-border: #333;
    --color-link: #7aa7ff; --color-link-hover: #a3c2ff;
    --pomo-surface: #262626; --pomo-highlight: #1a2233; --pomo-strong: #fff; --pomo-input-border: #6b6b6b;
    --pomo-disabled: #5c5c5c; --pomo-tick: #4a4a4a; --pomo-danger: #ff7b6e; --pomo-danger-hover: #ff9d93; --pomo-on-danger: #161616;
  }
}
:root[data-theme="dark"]:has(.pomo-body) { color-scheme: dark; }
:root[data-theme="dark"] .pomo-body {
  --color-bg: #161616; --color-text: #e8e8e8; --color-text-light: #a3a3a3; --color-border: #333;
  --color-link: #7aa7ff; --color-link-hover: #a3c2ff;
  --pomo-surface: #262626; --pomo-highlight: #1a2233; --pomo-strong: #fff; --pomo-input-border: #6b6b6b;
  --pomo-disabled: #5c5c5c; --pomo-tick: #4a4a4a; --pomo-danger: #ff7b6e; --pomo-danger-hover: #ff9d93; --pomo-on-danger: #161616;
}
.pomo-page { padding-top: max(1.5rem, env(safe-area-inset-top)); padding-bottom: max(4rem, env(safe-area-inset-bottom)); }
/* (0,2,0): beats every display rule below, so `hidden` always hides. */
.pomo-page [hidden] { display: none; }
.pomo-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; margin-bottom: 1.5rem; }
.pomo-site { margin: 0; font-size: 0.95rem; color: var(--color-text-light); }
.pomo-forget-area { display: flex; flex-wrap: wrap; justify-content: flex-end; }
/* FAHDS-257: the dark mode toggle, an icon button fixed to the bottom-right. aria-label names it and
   aria-pressed carries the state; the sun shows in light, the moon in dark. Below the toast (z 20). */
.pomo-theme-toggle {
  position: fixed; z-index: 10; right: max(1rem, env(safe-area-inset-right)); bottom: max(1rem, env(safe-area-inset-bottom));
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  margin: 0; padding: 0; border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-bg);
  color: var(--color-text-light); cursor: pointer; touch-action: manipulation;
}
.pomo-theme-toggle:hover { background: var(--pomo-surface); color: var(--color-text); }
.pomo-theme-toggle:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-theme-icon { display: block; }
.pomo-theme-toggle[aria-pressed="true"] .pomo-theme-sun, .pomo-theme-toggle:not([aria-pressed="true"]) .pomo-theme-moon { display: none; }
.pomo-page h1 { font-family: var(--font-display); font-size: 1.6rem; font-weight: 600; line-height: 1.25; letter-spacing: -0.02em; margin: 0 0 1rem; color: var(--color-text); }
.pomo-page h2 { font-size: 0.8125rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-light); margin: 0 0 1rem; }
.pomo-page h1:focus, .pomo-page h2:focus, .pomo-page h3:focus, .pomo-page h4:focus, .pomo-status:focus { outline: none; }
.pomo-page h1:focus-visible, .pomo-page h3:focus-visible, .pomo-page h4:focus-visible { outline: 2px solid var(--color-link); outline-offset: 4px; border-radius: 4px; }
.pomo-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Tabs (human change, 2026-09-12): Timer | Pomo | Log. The bar and the running strip stick to the
   top so the timer is never out of reach; focus targets scroll clear of it. */
.pomo-tabbar {
  position: sticky; top: 0; z-index: 10; margin: 0 0 1rem; padding-top: env(safe-area-inset-top);
  background: var(--color-bg); border-bottom: 1px solid var(--color-border);
}
.pomo-tabs { display: grid; grid-template-columns: repeat(4, 1fr); }
.pomo-tab {
  box-sizing: border-box; min-height: 56px; margin: 0; padding: 0.5rem; border: 0; border-bottom: 3px solid transparent;
  background: transparent; color: var(--color-text-light); font: inherit; font-size: 1.05rem; font-weight: 600;
  cursor: pointer; touch-action: manipulation;
}
.pomo-tab:hover { color: var(--color-text); }
.pomo-tab[aria-selected="true"] { color: var(--color-text); border-bottom-color: var(--color-text); }
.pomo-tab:focus-visible { outline: 2px solid var(--color-link); outline-offset: -4px; border-radius: 6px; }
.pomo-strip { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.5rem 0; border-top: 1px solid var(--color-border); }
.pomo-strip-text { margin: 0; font-size: 1rem; color: var(--color-text-light); }
.pomo-strip-elapsed { color: var(--color-text); font-weight: 600; font-size: 1.25rem; font-variant-numeric: tabular-nums; }
.pomo-page .pomo-strip-stop { min-width: 6.5rem; }
.pomo-app button, .pomo-app input, .pomo-app select, .pomo-app textarea, .pomo-app [tabindex="-1"] { scroll-margin-top: 13rem; }
.pomo-panel:focus { outline: none; }
.pomo-panel:focus-visible { outline: 2px solid var(--color-link); outline-offset: 4px; border-radius: 4px; }
.pomo-help, .pomo-hint, .pomo-meta, .pomo-key-reason { font-size: 0.95rem; color: var(--color-text-light); margin: 0 0 0.75rem; }
.pomo-key-reason { color: var(--color-text); font-weight: 600; }
.pomo-optional { font-weight: 400; color: var(--color-text-light); }
/* FAHDS-223: end-of-day metadata follows the selected date as one labeled section. */
.pomo-end-of-day { margin-top: 1.5rem; }
.pomo-page .pomo-end-of-day > h4,
.pomo-page .pomo-activities > h4 { margin: 0; font-size: 1.05rem; font-weight: 650; line-height: 1.4; color: var(--color-text); }
.pomo-day-summary { margin-top: 1rem; }
.pomo-form.pomo-day-summary label { margin-top: 0; }
.pomo-day-summary-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 0.5rem; }
.pomo-day-summary-row textarea { min-width: 0; }
.pomo-day-summary .pomo-hint { margin: 0.375rem 0 0; }
/* FAHDS-209: the day title field under the Log tab's date nav. */
.pomo-day-title { margin-top: 1rem; }
.pomo-form.pomo-day-title label { margin-top: 0; } /* beats .pomo-form label below (code review) */
.pomo-day-title-row { display: flex; gap: 0.5rem; }
.pomo-day-title-row input { flex: 1; min-width: 0; }
.pomo-day-title .pomo-hint { margin: 0.375rem 0 0; }
.pomo-day-photo { margin-top: 1rem; }
.pomo-day-photo-label { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.pomo-day-photo-preview { margin-top: 0.625rem; }
.pomo-day-photo-preview:empty { display: none; }
.pomo-day-photo-caption-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.75rem; }
.pomo-day-photo-caption-row label { flex-basis: 100%; }
.pomo-day-photo-caption-row input { flex: 1 1 14rem; min-width: 0; }
.pomo-day-photo-figure { margin: 0; }
.pomo-day-photo-figure img { display: block; width: min(100%, 24rem); height: auto; border-radius: 8px; background: var(--pomo-surface); }
.pomo-day-photo-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.75rem; }
.pomo-day-photo-actions .pomo-field-error { flex-basis: 100%; min-width: 0; overflow-wrap: anywhere; }
.pomo-day-photo-confirm { margin-top: 0.75rem; }
.pomo-day-photo-confirm > p { margin: 0 0 0.5rem; overflow-wrap: anywhere; }
.pomo-form { display: flex; flex-direction: column; align-items: stretch; }
.pomo-form label { display: block; margin: 1rem 0 0.375rem; font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.pomo-page input[type="text"], .pomo-page input[type="url"], .pomo-page input[type="password"], .pomo-page input[type="date"], .pomo-page input[type="time"], .pomo-page input[type="number"], .pomo-page select, .pomo-page textarea {
  box-sizing: border-box; display: block; width: 100%; min-width: 0; min-height: 48px; padding: 0.625rem 0.75rem;
  border: 1px solid var(--pomo-input-border); border-radius: 8px; background: var(--color-bg); color: var(--color-text);
  font: inherit; font-size: 16px; line-height: 1.4;
}
.pomo-page textarea { resize: vertical; min-height: 6rem; }
.pomo-page input:focus-visible, .pomo-page select:focus-visible, .pomo-page textarea:focus-visible { outline: 2px solid var(--color-link); outline-offset: 1px; }
.pomo-page [aria-invalid="true"] { border-color: var(--pomo-danger); }
.pomo-error, .pomo-field-error { margin: 0.375rem 0 0; font-size: 0.95rem; color: var(--pomo-danger); overflow-wrap: anywhere; }
.pomo-error:empty, .pomo-field-error:empty, .pomo-hint:empty { display: none; }
/* Buttons: 48px minimum at every width. */
.pomo-button {
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; min-height: 48px; min-width: 48px;
  padding: 0.5rem 1rem; border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-bg);
  color: var(--color-text); font: inherit; font-size: 1rem; font-weight: 600; line-height: 1.2; cursor: pointer;
  touch-action: manipulation;
}
.pomo-button:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--pomo-surface); }
.pomo-button:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-button:disabled, .pomo-button[aria-disabled="true"] { cursor: default; color: var(--color-text-light); background: var(--pomo-surface); }
.pomo-button-primary { background: var(--color-text); border-color: var(--color-text); color: var(--color-bg); }
.pomo-button-primary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--pomo-strong); }
.pomo-button-primary:disabled, .pomo-button-primary[aria-disabled="true"] { background: var(--color-text-light); border-color: var(--color-text-light); color: var(--color-bg); }
.pomo-button-big { min-height: 64px; font-size: 1.25rem; margin-top: 1.25rem; }
.pomo-button-wide { margin-top: 1.25rem; }
.pomo-button-quiet { border-color: transparent; background: transparent; color: var(--color-text-light); font-weight: 500; }
.pomo-button-danger { background: var(--pomo-danger); border-color: var(--pomo-danger); color: var(--pomo-on-danger); }
.pomo-button-danger:hover:not(:disabled) { background: var(--pomo-danger-hover); border-color: var(--pomo-danger-hover); }
.pomo-button-danger-quiet { color: var(--pomo-danger); }
.pomo-confirm { margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--color-border); border-radius: 10px; }
.pomo-confirm p { margin: 0 0 0.5rem; }
/* At least 8px between the destructive and the safe button. */
.pomo-confirm-buttons { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.pomo-status { margin: 0 0 1rem; min-height: 1.6em; color: var(--color-text); overflow-wrap: anywhere; }
.pomo-status-live-hidden { height: 1.6em; overflow: hidden; clip-path: inset(50%); color: transparent; }
.pomo-toast {
  position: fixed; z-index: 20; left: max(1rem, env(safe-area-inset-left)); right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom)); box-sizing: border-box; width: fit-content;
  max-width: min(36rem, calc(100vw - max(1rem, env(safe-area-inset-left)) - max(1rem, env(safe-area-inset-right))));
  margin-inline: auto; padding: 0.75rem 1rem; border-radius: 8px; background: var(--color-text); color: var(--color-bg);
  line-height: 1.4; overflow-wrap: anywhere; pointer-events: none; animation: pomo-toast-rise 3.8s ease-out both;
}
@keyframes pomo-toast-rise {
  0% { opacity: 0; transform: translateY(0.75rem); }
  10%, 72% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-1rem); }
}
@keyframes pomo-toast-fade {
  0% { opacity: 0; }
  10%, 72% { opacity: 1; }
  100% { opacity: 0; }
}
.pomo-sync { margin: 0 0 0.75rem; font-size: 0.95rem; color: var(--pomo-danger); }
.pomo-loading p { margin: 0 0 0.75rem; color: var(--color-text-light); }
.pomo-running #pomo-discard { align-self: center; margin-top: 0.75rem; }
.pomo-elapsed { margin: 0; font-size: clamp(3rem, 16vw, 4.5rem); font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--color-text); }
.pomo-meta { margin: 0.125rem 0 0; }
.pomo-save-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 1rem; }
.pomo-conflict { margin: 0; font-size: 0.95rem; color: var(--pomo-danger); }
.pomo-photo-pick { position: relative; }
.pomo-page .pomo-photo-pick .pomo-file-label { display: inline-flex; margin: 0; font-size: 1rem; }
.pomo-gallery-editor { margin-top: 1rem; }
.pomo-gallery-list {
  display: flex; flex-flow: row wrap; align-items: center; justify-content: flex-start; gap: 0.75rem; margin: 0.5rem 0;
}
.pomo-gallery-list.is-empty { justify-content: flex-start; }
.pomo-gallery-item, .pomo-gallery-add {
  position: relative; box-sizing: border-box; flex: 0 0 9rem; width: 9rem; min-width: 9rem; margin: 0; border-radius: 10px;
}
.pomo-gallery-item { overflow: hidden; border: 1px solid var(--color-border); background: var(--pomo-surface); }
.pomo-gallery-media { display: grid; width: 100%; height: 9rem; place-items: center; color: var(--color-text-light); }
.pomo-gallery-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pomo-gallery-item-actions { position: absolute; top: 0.25rem; right: 0.25rem; display: flex; align-items: center; gap: 0.25rem; }
.pomo-gallery-remove {
  position: relative; isolation: isolate; display: grid; width: 44px; height: 44px; place-items: center;
  padding: 0; border: 0; border-radius: 999px; background: transparent;
  color: #fff; font: inherit; font-size: 1.75rem; line-height: 1; cursor: pointer;
}
.pomo-gallery-remove::before {
  position: absolute; z-index: -1; width: 32px; height: 32px; border: 1px solid rgb(255 255 255 / 70%);
  border-radius: 50%; background: rgb(0 0 0 / 72%); content: "";
}
.pomo-gallery-remove:disabled { opacity: 0.55; cursor: default; }
.pomo-gallery-remove:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-gallery-retry {
  min-height: 44px; padding: 0 0.65rem; border: 1px solid currentColor; border-radius: 1.4rem;
  color: #fff; background: rgb(0 0 0 / 72%); font: inherit; cursor: pointer;
}
.pomo-gallery-item figcaption { padding: 0.375rem; color: var(--pomo-danger); font-size: 0.8125rem; line-height: 1.25; }
.pomo-gallery-caption { box-sizing: border-box; display: block; width: calc(100% - 0.5rem); margin: 0.25rem; font: inherit; font-size: 0.8rem; }
.pomo-gallery-caption-save { display: block; margin: 0 0.25rem 0.35rem; padding: 0.2rem 0.3rem; border: 0; background: transparent; color: var(--color-link); font: inherit; font-size: 0.8rem; text-decoration: underline; cursor: pointer; }
.pomo-gallery-caption-save:disabled { opacity: 0.55; cursor: default; }
.pomo-gallery-add {
  display: grid; height: 9rem; min-height: 9rem; place-items: center; padding: 0.75rem; border: 2px dashed var(--pomo-input-border);
  background: var(--color-bg); color: var(--color-text); font-weight: 600; line-height: 1.3; text-align: center; cursor: pointer;
}
.pomo-form label.pomo-gallery-add { display: grid; margin: 0; place-items: center; }
.pomo-gallery-add:hover, .pomo-gallery-add.is-dragover { border-color: var(--color-link); background: var(--pomo-highlight); }
.pomo-file-hidden:focus-visible + .pomo-gallery-add, .pomo-gallery-add:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-gallery-status:empty { display: none; }
.pomo-pending { margin: 1rem 0 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.pomo-pending-img { display: block; width: 160px; height: auto; border-radius: 8px; background: var(--pomo-surface); }
.pomo-pending figcaption { font-size: 0.95rem; color: var(--color-text-light); }
.pomo-day-nav { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0.5rem; }
.pomo-page .pomo-day-nav h3 { min-width: 0; margin: 0; text-align: center; font-size: 1.15rem; font-weight: 600; line-height: 1.3; color: var(--color-text); }
.pomo-day-trigger {
  box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: 100%; min-width: 0; min-height: 48px;
  margin: 0; padding: 0.375rem; border: 0; border-radius: 4px; background: transparent; color: inherit;
  font: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; text-align: center; cursor: pointer; touch-action: manipulation;
  anchor-name: --pomo-day-trigger;
}
.pomo-day-heading-text { min-width: 0; overflow-wrap: anywhere; }
.pomo-day-trigger:hover:not(:disabled) { text-decoration: underline; }
.pomo-day-trigger:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-day-trigger:disabled { cursor: default; }
.pomo-calendar {
  position: fixed; inset: min(30vh, 12rem) 1rem auto; box-sizing: border-box; width: min(24rem, calc(100vw - 2rem));
  max-height: min(34rem, calc(100vh - 2rem)); max-height: min(34rem, calc(100dvh - 2rem)); margin: 0 auto;
  padding: 1rem; overflow: auto; overscroll-behavior: contain; border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg); color: var(--color-text); box-shadow: 0 0.75rem 2rem rgb(0 0 0 / 18%);
}
.pomo-calendar[open] { display: block; transform: none; animation: pomo-calendar-reveal 140ms ease-out both; }
.pomo-calendar::backdrop { background: rgb(0 0 0 / 28%); touch-action: none; }
.pomo-calendar-header { display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px 44px; align-items: center; gap: 0.25rem; }
.pomo-page .pomo-calendar-header h4 { margin: 0; text-align: center; font-size: 1.05rem; font-weight: 650; line-height: 1.3; color: var(--color-text); }
.pomo-calendar-icon, .pomo-calendar-day {
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px;
  margin: 0; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--color-text); font: inherit;
  line-height: 1; cursor: pointer; touch-action: manipulation;
}
.pomo-calendar-icon { font-size: 1.5rem; }
.pomo-calendar-close { color: var(--color-text-light); }
.pomo-calendar-icon:hover:not(:disabled), .pomo-calendar-day:hover:not(:disabled) { background: var(--pomo-surface); }
.pomo-calendar-icon:focus-visible, .pomo-calendar-day:focus-visible { outline: 2px solid var(--color-link); outline-offset: 1px; }
.pomo-calendar-icon:disabled { color: var(--pomo-disabled); cursor: default; }
.pomo-calendar-weekdays, .pomo-calendar-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.375rem; }
.pomo-calendar-weekdays { color: var(--color-text-light); font-size: 0.8125rem; font-weight: 600; text-align: center; }
.pomo-calendar-weekdays span { display: grid; min-width: 44px; min-height: 44px; place-items: center; }
.pomo-calendar-grid { margin-top: 0.75rem; }
.pomo-calendar-rows { margin-top: 0.125rem; }
.pomo-calendar-row + .pomo-calendar-row { margin-top: 0.375rem; }
.pomo-calendar-day { width: 100%; font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.pomo-calendar-day[aria-selected="true"] { background: var(--color-text); color: var(--color-bg); font-weight: 650; }
.pomo-calendar-day[aria-current="date"] { box-shadow: inset 0 -3px 0 currentColor; font-weight: 650; }
.pomo-calendar-day[aria-selected="true"]:hover { background: var(--pomo-strong); }
.pomo-calendar-day:disabled { color: var(--pomo-disabled); cursor: default; }
.pomo-calendar-day-spill { min-width: 44px; min-height: 44px; visibility: hidden; }
.pomo-calendar-open { overflow: hidden; }
@supports (position-area: bottom) {
  .pomo-calendar { position-anchor: --pomo-day-trigger; position-area: bottom center; inset: auto; margin-block-start: 0.5rem; }
}
@keyframes pomo-calendar-reveal { from { opacity: 0; transform: translateY(-0.375rem); } to { opacity: 1; transform: none; } }
.pomo-arrow { font-size: 1.75rem; font-weight: 400; padding: 0; border-color: transparent; }
.pomo-activities-divider { margin-block: clamp(3rem, calc(4vw + 1.5rem), 5rem); margin-inline: 0; border: 0; border-top: 1px solid var(--color-border); }
.pomo-activities { margin: 0; }
.pomo-activities-header { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.pomo-page .pomo-activities-header > h4 { margin: 0; font-size: 1.05rem; font-weight: 650; line-height: 1.4; color: var(--color-text); }
.pomo-manual-form { margin-top: 1rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--color-border); }
.pomo-manual-form > label:first-child { margin-top: 0; }
.pomo-manual-times { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
.pomo-manual-times > div { min-width: 0; }
.pomo-manual-actions { justify-content: flex-end; margin-top: 1rem; }
.pomo-entry-list { list-style: none; margin: 0.25rem 0 0; padding: 0; }
.pomo-entry { padding: 1rem 0 1.25rem; border-bottom: 1px solid var(--color-border); }
.pomo-entry-highlight { background: var(--pomo-highlight); box-shadow: -0.75rem 0 0 var(--pomo-highlight), 0.75rem 0 0 var(--pomo-highlight); }
.pomo-entry-time { margin: 0; font-size: 0.95rem; color: var(--color-text-light); font-variant-numeric: tabular-nums; }
.pomo-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; margin: 0.25rem 0 0; }
.pomo-badge { font-size: 0.8125rem; font-weight: 600; padding: 0.1rem 0.5rem; border-radius: 999px; border: 1px solid var(--color-text-light); color: var(--color-text); }
.pomo-badge-auto { border-color: var(--pomo-danger); color: var(--pomo-danger); }
/* FAHDS-206: read-only category badge with a coloured dot (class, not inline style: CSP style-src 'self'). */
.pomo-cat { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.8125rem; color: var(--color-text); }
.pomo-cat[hidden] { display: none; }
.pomo-cat::before { content: ""; flex: none; box-sizing: border-box; width: 0.5rem; height: 0.5rem; border-radius: 50%; border: 1px solid var(--cat-dot, var(--color-text-light)); background: var(--cat-dot, var(--color-bg)); }
.pomo-pomodoro-category-field { min-width: 0; margin-top: 1rem; text-align: left; }
.pomo-page .pomo-pomodoro-category-field label { display: block; margin: 0 0 0.375rem; font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.pomo-page .pomo-entry-title { margin: 0.375rem 0 0; font-size: 1.05rem; font-weight: 650; line-height: 1.4; overflow-wrap: anywhere; color: var(--color-text); }
.pomo-entry-summary { margin: 0.25rem 0 0; white-space: pre-line; overflow-wrap: anywhere; color: var(--color-text-light); }
.pomo-entry-photo { margin: 0.625rem 0 0; }
.pomo-entry-photo img { display: block; width: 160px; height: auto; border-radius: 8px; background: var(--pomo-surface); }
.pomo-photo-missing { font-size: 0.95rem; color: var(--color-text-light); }
.pomo-entry-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.5rem; margin-top: 0.75rem; }
.pomo-entry-actions-primary { display: flex; flex-wrap: nowrap; align-items: center; gap: 0.5rem; min-width: 0; }
.pomo-entry-actions .pomo-button { white-space: nowrap; }
.pomo-entry-actions > .pomo-button-danger-quiet { justify-self: end; }
.pomo-entry-photo-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.75rem; }
.pomo-entry-photo-actions .pomo-field-error { flex-basis: 100%; }
.pomo-entry-edit { margin-top: 0.5rem; }
.pomo-entry-edit .pomo-manual-times { margin-top: 0; }
.pomo-entry-edit .pomo-confirm-buttons { margin-top: 0.75rem; }
.pomo-entry-edit-actions { justify-content: flex-end; }
.pomo-subtasks { list-style: none; margin: 0.75rem 0 0 0.25rem; padding: 0 0 0 0.5rem; border-left: 1px solid color-mix(in srgb, var(--color-border) 55%, var(--color-bg)); }
.pomo-subtask { padding: 0.5rem 0; border-bottom: 1px solid var(--color-border); }
.pomo-subtask:last-child { border-bottom: 0; }
.pomo-subtask-time { margin: 0; color: var(--color-text-light); font-size: 0.875rem; font-variant-numeric: tabular-nums; }
.pomo-subtask-title { margin: 0.25rem 0 0; font-size: 1rem; overflow-wrap: anywhere; }
.pomo-subtask-summary { margin: 0.25rem 0 0; color: var(--color-text-light); white-space: pre-line; overflow-wrap: anywhere; }
.pomo-subtask-actions { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.5rem; }
.pomo-subtask-form { margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--color-border); border-radius: 8px; }
.pomo-subtask-add { margin-top: 0.75rem; }
.pomo-running-subtasks { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--color-border); }
.pomo-running-subtasks-heading-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.pomo-running-subtasks h3 { margin: 0; font-size: 1rem; }
.pomo-subtask-capture {
  flex: 0 0 44px; width: 44px; min-width: 44px; max-width: 44px; height: 44px; min-height: 44px;
  padding: 0; font-size: 1.75rem; line-height: 1;
}
.pomo-subtask-row-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.pomo-subtask-row-header .pomo-subtask-time { flex: 1; color: var(--color-text); font-weight: 600; overflow-wrap: anywhere; }
.pomo-subtask-delete-icon { min-width: 44px; min-height: 44px; padding: 0; color: var(--pomo-danger); font-size: 1.25rem; line-height: 1; }
.pomo-live-subtask-form h4 { margin: 0 0 0.75rem; font-size: 1rem; }
.pomo-live-subtask-form input:not(.pomo-file-hidden), .pomo-live-subtask-form textarea { width: 100%; }
.pomo-live-subtask-form [aria-invalid="true"] { border-color: var(--pomo-danger); }
.pomo-running-subtask-active { padding: 0.75rem; border-radius: 8px; background: var(--pomo-highlight); }
.pomo-running-subtask-elapsed { font-variant-numeric: tabular-nums; font-weight: 650; }
/* The card's file input is visually hidden but stays focusable; its label is the visible button. */
.pomo-file-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); border: 0; opacity: 0; }
.pomo-file-hidden:focus-visible + .pomo-file-label { outline: 2px solid var(--color-link); outline-offset: 2px; }
.pomo-file-label[aria-disabled="true"] { cursor: default; color: var(--color-text-light); background: var(--pomo-surface); }
.pomo-empty, .pomo-noscript { color: var(--color-text-light); margin: 1rem 0; }

@media (max-width: 640px) {
  .pomo-calendar {
    inset: auto 0 0; width: 100%; max-width: none; max-height: calc(100vh - env(safe-area-inset-top) - 0.5rem);
    max-height: calc(100dvh - env(safe-area-inset-top) - 0.5rem); margin: 0; padding: 1rem max(0.75rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(0.75rem, env(safe-area-inset-left));
    border-right: 0; border-bottom: 0; border-left: 0; border-radius: 8px 8px 0 0;
    position-anchor: auto; position-area: unset;
  }
  .pomo-calendar[open] { animation-name: pomo-calendar-sheet-reveal; }
}
@media (max-width: 520px) {
  .pomo-day-summary-row { grid-template-columns: minmax(0, 1fr); }
  .pomo-day-summary-row .pomo-button { justify-self: end; }
  .pomo-manual-times { grid-template-columns: 1fr; gap: 0; }
  .pomo-subtask-photo img, .log-subtask-photo img { width: 100%; }
}
@media (max-width: 420px) {
  .pomo-entry-actions { gap: 0.1875rem; }
  .pomo-entry-actions-primary { gap: 0.1875rem; }
  .pomo-entry-actions .pomo-button { padding-inline: 0.1875rem; font-size: 0.75rem; }
}
@media (max-width: 360px) {
  .pomo-calendar { padding-right: max(0.375rem, env(safe-area-inset-right)); padding-left: max(0.375rem, env(safe-area-inset-left)); }
  .pomo-calendar-weekdays, .pomo-calendar-row { gap: 0; }
  .pomo-calendar-row + .pomo-calendar-row { margin-top: 0; }
}
@keyframes pomo-calendar-sheet-reveal { from { opacity: 0; transform: translateY(0.75rem); } to { opacity: 1; transform: none; } }

/* FAHDS-198: /pomo Pomo tab
   The pomodoro dial. Site tokens only; no inline styles anywhere (CSP style-src 'self'): the ring
   moves through its stroke-dashoffset attribute and colours follow data-phase / data-empty. Nothing
   animates, so the reduced-motion block above needs nothing more. */
.pomo-strip-actions { display: flex; align-items: center; gap: 0.25rem; }
.pomo-pomodoro-view { display: flex; flex-direction: column; align-items: stretch; }
.pomo-pomodoro-activity { text-align: center; }
.pomo-page .pomo-pomodoro-title-input, .pomo-pomodoro-name {
  font-size: 1.35rem; font-weight: 600; line-height: 1.3; text-align: center; color: var(--color-text);
}
.pomo-page .pomo-pomodoro-title-input { border-color: var(--color-border); }
/* The shared input rule sets display: block at (0,2,1), above `.pomo-page [hidden]`. */
.pomo-page .pomo-pomodoro-title-input[hidden] { display: none; }
.pomo-page .pomo-pomodoro-title-input::placeholder { color: var(--color-text-light); font-weight: 500; }
.pomo-pomodoro-name { margin: 0; padding: 0.5rem 0; overflow-wrap: anywhere; }
.pomo-pomodoro-subtitle { margin: 0.25rem 0 0; font-size: 0.95rem; color: var(--color-text-light); }
.pomo-dial { display: grid; width: min(80vw, 20rem); max-width: 100%; aspect-ratio: 1; margin: 1.5rem auto 0; }
.pomo-dial > * { grid-area: 1 / 1; }
.pomo-dial-svg { display: block; width: 100%; height: 100%; }
.pomo-dial-track, .pomo-dial-ring { fill: none; stroke-width: 12; }
.pomo-dial-track { stroke: var(--color-border); }
.pomo-dial[data-idle="true"][data-phase="focus"] .pomo-dial-track { stroke: var(--cat-dot, var(--color-border)); }
.pomo-dial-ring { stroke: var(--color-text); stroke-linecap: round; }
.pomo-dial[data-phase="focus"] .pomo-dial-ring { stroke: var(--cat-dot, var(--color-text)); }
.pomo-dial[data-phase="break"] .pomo-dial-ring { stroke: var(--color-link); }
.pomo-dial-ring[data-empty="true"] { stroke-opacity: 0; }
.pomo-dial-tick { stroke: var(--pomo-tick); stroke-width: 1.5; stroke-linecap: round; }
.pomo-dial-tick-major { stroke: var(--color-text-light); stroke-width: 2.5; }
.pomo-dial-center { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.pomo-dial-center p { margin: 0; }
.pomo-dial-phase { font-size: 0.8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-light); }
.pomo-dial[data-phase="break"] .pomo-dial-phase { color: var(--color-link); }
.pomo-dial-countdown { font-size: clamp(3rem, 15vw, 4.25rem); font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--color-text); }
.pomo-dial-state { font-size: 0.95rem; color: var(--color-text-light); max-width: 11rem; }
.pomo-pomodoro-url-field { box-sizing: border-box; width: 100%; min-width: 0; margin-top: 1rem; text-align: left; }
.pomo-page .pomo-pomodoro-url-field label { display: block; margin: 0 0 0.375rem; font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.pomo-pomodoro-view .pomo-button-big + .pomo-button-big { margin-top: 0.75rem; }
.pomo-page .pomo-disclosure { align-self: center; margin-top: 0.5rem; }
.pomo-disclosure-icon { display: inline-block; margin-left: 0.375rem; }
.pomo-disclosure[aria-expanded="true"] .pomo-disclosure-icon { transform: rotate(90deg); }
.pomo-pomodoro-settings { display: flex; flex-direction: column; align-items: stretch; }
.pomo-pomodoro-settings label { display: block; margin: 1rem 0 0.375rem; font-size: 0.95rem; font-weight: 600; color: var(--color-text); }
.pomo-pomodoro-settings .pomo-help { margin-top: 0.75rem; }
.pomo-page input:disabled, .pomo-page select:disabled { color: var(--color-text-light); background: var(--pomo-surface); }

/* FAHDS-261: public photo grids and compact activity action menus. */
.pomo-entry-photo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(5rem, 1fr)); gap: .5rem; }
.pomo-entry-photo-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.pomo-action-menu { position: relative; margin-left: auto; }
.pomo-action-menu-trigger { min-width: 2.75rem; min-height: 2.75rem; font-size: 1.4em; line-height: 1; }
.pomo-action-menu-popup { position: absolute; z-index: 20; right: 0; min-width: 10rem; padding: .35rem; border: 1px solid var(--color-border); border-radius: .65rem; background: var(--pomo-surface); box-shadow: 0 .5rem 1.5rem rgba(0,0,0,.18); }
.pomo-action-menu-item { display: block; width: 100%; padding: .65rem .8rem; border: 0; border-radius: .4rem; color: var(--color-text); background: transparent; font: inherit; text-align: left; cursor: pointer; }
.pomo-action-menu-item:hover, .pomo-action-menu-item:focus-visible { background: color-mix(in srgb, var(--color-text) 9%, transparent); outline: none; }
.pomo-action-menu-item.is-danger { color: var(--pomo-danger); }
.pomo-action-menu-separator { margin: .3rem; border-top: 1px solid var(--color-border); }

/* Selected-day publication is independent of contribution visibility. */
.pomo-day-publication-row { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.pomo-day-publication { display: inline-flex; align-items: center; gap: .4rem; }
.pomo-day-publication svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; }
.pomo-day-publication svg[hidden] { display: none; }
.pomo-day-publication[aria-pressed="true"] { border-color: currentColor; }

/* Publication controls are opt-in: private dates never navigate. */
.log-post-date a, a.log-heatmap-popup-date { text-decoration: underline; text-underline-offset: .15em; }
.log-post-item.is-private, .log-post-item.is-private .log-post-tile, .log-heatmap-cell[data-private="true"] { cursor: not-allowed; }
.log-post-item.is-private .log-post-tile, .log-post-item.is-private .log-post-thumb { position: relative; }
.log-post-item.is-private .log-post-thumb { overflow: visible; }
.log-post-item.is-private .log-post-thumb img { border-radius: inherit; }
.log-post-lock { position: absolute; top: -4px; left: -4px; z-index: 1; width: 14px; height: 14px; fill: var(--color-text-light); pointer-events: none; }
.log-post-private-status { font-size: .75rem; color: var(--muted); }

/* The generic unavailable day keeps private and missing dates indistinguishable. */
.log-private-lock { display: block; width: 64px; height: 64px; margin: 1.5rem auto 0; }
.log-private-message { display: flex; flex-direction: column; align-items: center; gap: 1rem; text-align: center; }

/* FAHDS-441: the /pomo Meetings tab. */
/* FAHDS-452: status and Refresh share one row right under the tab bar (no empty gap). The shared
   live region keeps its reserved line on the timer tabs only; on Meetings it collapses while empty
   (still rendered, so it keeps announcing). */
.pomo-app:has(#pomo-meetings:not([hidden])) .pomo-status:empty { min-height: 0; margin: 0; }
.pomo-app:has(#pomo-meetings:not([hidden])) .pomo-status.pomo-status-live-hidden { min-height: 0; height: 1px; margin: 0; }
.pomo-meetings-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin: -0.25rem 0 0; min-height: 2.5rem; }
.pomo-meetings-status { margin: 0; font-size: 0.95rem; color: var(--color-text-light); }
.pomo-meetings-bar > .pomo-button { margin-left: auto; }
.pomo-meetings-section { margin: 0.75rem 0 1.25rem; }
.pomo-meetings-section:first-of-type { margin-top: 0.25rem; }
.pomo-meetings-title { margin: 0 0 0.5rem; font-size: 1rem; color: var(--color-text-light); font-weight: 600; }
.pomo-meetings-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.pomo-meeting { border: 1px solid color-mix(in srgb, currentColor 15%, transparent); border-radius: 10px; padding: 0.75rem; min-width: 0; }
.pomo-meeting-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 0.75rem; }
.pomo-meeting-name { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.pomo-meeting-when, .pomo-meeting-code { margin: 0.25rem 0 0; color: var(--color-text-light); overflow-wrap: anywhere; }
.pomo-meeting-value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--color-text); }
.pomo-meeting-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.pomo-meeting-kind { display: inline-block; margin-right: 0.5rem; padding: 0.05rem 0.45rem; border-radius: 999px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.02em; vertical-align: 0.1em; color: var(--color-text-light); border: 1px solid color-mix(in srgb, currentColor 30%, transparent); }
.pomo-meeting-settings { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin-top: 0.75rem; }
.pomo-meeting-setting { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; min-width: 0; }
.pomo-meeting-label { color: var(--color-text-light); }
.pomo-meeting-note { margin: 0.375rem 0 0; font-size: 0.85rem; color: var(--color-text-light); }
.pomo-meeting-plain { color: var(--color-text-light); }
.pomo-named-form + .pomo-empty, .pomo-named-form ~ .pomo-meetings-list { margin-top: 1rem; }
.pomo-segmented { display: inline-flex; }
.pomo-segmented > .pomo-segment { border-radius: 0; }
.pomo-segmented > .pomo-segment:first-child { border-radius: 8px 0 0 8px; }
.pomo-segmented > .pomo-segment:last-child { border-radius: 0 8px 8px 0; margin-left: -1px; }
.pomo-segmented > .pomo-segment[aria-pressed="true"] { background: var(--color-text); border-color: var(--color-text); color: var(--color-bg); }
.pomo-meeting-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.75rem; padding: 0.625rem; border-radius: 8px; border: 1px solid var(--pomo-danger); }
.pomo-meeting-confirm-text { flex-basis: 100%; margin: 0; overflow-wrap: anywhere; }
.pomo-named-form select { display: block; margin-bottom: 0.75rem; }
.pomo-blocks-intro { margin: 0 0 0.375rem; font-size: 0.9rem; color: var(--color-text-light); }
.pomo-blocks-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 0.75rem; }
.pomo-blocks-field { min-width: 0; }
.pomo-form label.pomo-blocks-check { display: flex; align-items: center; gap: 0.5rem; min-height: 48px; margin: 0.5rem 0 0; font-weight: 600; cursor: pointer; }
.pomo-blocks-check input { width: 1.25rem; height: 1.25rem; margin: 0; }
.pomo-blocks-form .pomo-button-primary { margin-top: 1rem; }
.pomo-blocks-form + .pomo-empty, .pomo-blocks-form ~ .pomo-meetings-list { margin-top: 1rem; }
.pomo-block-warning { margin: 0.5rem 0 0; padding: 0.5rem 0.625rem; border-radius: 8px; border-left: 3px solid var(--pomo-danger); background: color-mix(in srgb, var(--pomo-danger) 8%, transparent); font-size: 0.9rem; overflow-wrap: anywhere; }
.pomo-block-warning:empty { display: none; }
