/* Full-bleed banner: cancels #view's own padding (see css/app.css) so the
   hero spans the whole screen width, and reaches up past #view's top edge
   into env(safe-area-inset-top) — the status bar/notch strip on an
   installed PWA — instead of stopping short of it like a card would.
   --safe-top (tokens.css) is how far real content (buttons, text) must sit
   below that true top edge to clear both #view's usual top padding and the
   status bar's own icons. The sticky nav below (.dies-detail-nav) is pinned
   with position: fixed instead of bleeding via margin, but still uses the
   same --safe-top for its own padding so the two line up with no seam. */
.day-hero {
  position: relative;
  background: var(--accent); color: white;
  padding: calc(var(--safe-top) + var(--space-3)) var(--space-4) var(--space-5);
  border-bottom: 3px dashed color-mix(in srgb, white 40%, var(--accent));
  margin: calc(var(--safe-top) * -1) calc(var(--space-4) * -1) var(--space-5);
}
.day-hero__label { font-size: var(--text-sm); opacity: 0.85; }
.day-hero__title { font-size: var(--text-2xl); margin-top: var(--space-1); }
.day-hero__weather[hidden] { display: none; }
.day-hero__weather { margin-left: var(--space-2); font-weight: 600; }
.day-hero__stage {
  font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  opacity: 0.85; margin-top: var(--space-1);
}

.day-hero--photo {
  position: relative; overflow: hidden; border: none;
  padding: 0;
  height: calc(min(380px, 52vh) + var(--safe-top));
  background-size: cover; background-position: center 65%;
  display: flex; align-items: flex-end;
  animation: hero-reveal 700ms var(--ease-out) both;
}
@keyframes hero-reveal {
  from { opacity: 0; transform: scale(1.04); }
  to { opacity: 1; transform: scale(1); }
}
.day-hero__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent-strong) 35%, transparent) 0%,
    transparent 32%,
    transparent 50%,
    color-mix(in srgb, black 75%, var(--accent-strong)) 100%);
}
.day-hero--photo .day-hero__content {
  position: relative; z-index: 1;
  padding: var(--space-6) var(--space-5) var(--space-5);
  width: 100%;
}
.day-hero--photo .day-hero__label {
  display: inline-block;
  color: #fff; opacity: 1; text-transform: uppercase; letter-spacing: 0.06em;
  font-size: var(--text-xs); font-weight: 700;
  background: rgba(0,0,0,0.45); backdrop-filter: blur(6px);
  padding: 5px 12px; border-radius: 999px;
  text-shadow: none;
}
.day-hero--photo .day-hero__title {
  color: #fff; font-size: clamp(32px, 8vw, 44px); line-height: 1.05;
  margin-top: var(--space-2);
  text-shadow: 0 2px 16px rgba(0,0,0,0.4);
}
.day-hero--photo .day-hero__stage {
  color: #fff; text-shadow: 0 1px 8px rgba(0,0,0,0.35);
}
.day-hero__credit {
  position: absolute; z-index: 1; top: calc(var(--safe-top) + var(--space-3)); right: var(--space-3);
  font-size: 10px; color: rgba(255,255,255,0.85);
  background: rgba(0,0,0,0.35); backdrop-filter: blur(6px);
  padding: 4px 9px; border-radius: 999px;
  text-decoration: none; line-height: 1.4;
}
.day-hero__nav {
  position: absolute; z-index: 2; top: calc(var(--safe-top) + var(--space-3)); right: var(--space-3);
  display: flex; gap: var(--space-2);
}
.day-hero__back {
  position: absolute; z-index: 2; top: calc(var(--safe-top) + var(--space-3)); left: var(--space-3);
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(0,0,0,0.35); color: #fff; backdrop-filter: blur(6px);
  font-size: var(--text-lg); font-weight: 600; line-height: 1;
  transition: transform var(--dur-fast) var(--ease-out);
}
.day-hero__back:active { transform: scale(0.9); }
.day-hero__nav .dies-daynav__btn {
  background: rgba(0,0,0,0.35); color: #fff; backdrop-filter: blur(6px);
}

.day-intro {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--accent-soft); border-radius: var(--radius-md);
  padding: var(--space-4); margin-bottom: var(--space-5);
  border: 1px dashed color-mix(in srgb, var(--accent) 35%, transparent);
}
.day-intro__icon { font-size: var(--text-xl); line-height: 1; flex-shrink: 0; }
.day-intro__text {
  font-family: var(--font-display); font-size: var(--text-lg); line-height: 1.45;
  color: var(--accent-strong);
}

.day-route-link { margin-bottom: var(--space-5); }

.day-timeline { display: flex; flex-direction: column; gap: var(--space-4); list-style: none; }
.activity-card {
  background: var(--bg-elevated); border-radius: var(--radius-md);
  padding: var(--space-4); box-shadow: var(--shadow-sm);
}
.activity-card__meta { font-size: var(--text-sm); color: var(--text-muted); display: flex; gap: var(--space-2); align-items: baseline; }
.activity-card__lock-icon { cursor: help; }
.activity-card__time { font-size: var(--text-lg); color: var(--text); }
.activity-card__title { font-size: var(--text-lg); font-weight: 600; margin-top: var(--space-1); }
.activity-card__desc { font-size: var(--text-base); color: var(--text-muted); margin-top: var(--space-1); }
.activity-card__links { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); }

.activity-card--collapsed {
  padding: var(--space-3) var(--space-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  opacity: 0.6; cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.activity-card--collapsed:active { transform: scale(0.98); opacity: 0.8; }
.activity-card--collapsed .activity-card__meta { margin: 0; }
.activity-card--collapsed .activity-card__collapsed-title {
  color: var(--text); text-decoration: line-through; text-decoration-color: var(--border);
}
.activity-card__expand-hint { font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; }

.activity-card--visitable { cursor: pointer; }
.activity-card--visitable:active { transform: scale(0.99); }
.activity-card__expand-hint--visit {
  display: block; margin-top: var(--space-2); color: var(--accent); font-weight: 600;
}
.activity-card__visit {
  display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.activity-card__visit.is-open { grid-template-rows: 1fr; opacity: 1; }
.activity-card__visit-inner { overflow: hidden; }
.activity-card__visit.is-open .activity-card__visit-inner { margin-top: var(--space-3); }
.activity-card__photo {
  display: block; width: 100%; height: 180px; object-fit: cover;
  border-radius: var(--radius-md);
}
/* Opt-in via visit.imageContain (day-render.js) for an illustration whose
   whole frame matters (nothing to crop off). The fixed 180px height forces
   either cropping (cover) or side letterboxing (contain) whenever the
   image's own aspect ratio doesn't match the card — auto height sidesteps
   both: the image keeps its native ratio and fills the full card width. */
.activity-card__photo--contain {
  height: auto;
}
.activity-card__detail {
  font-size: var(--text-base); color: var(--text); line-height: 1.5;
  margin-top: var(--space-3);
}
.activity-card__reco {
  font-size: var(--text-sm); color: var(--accent-strong); background: var(--accent-soft);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  margin-top: var(--space-2);
}
.activity-card__visit-link { display: inline-block; margin-top: var(--space-2); text-decoration: none; }
.chip {
  font-size: var(--text-xs); padding: 6px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); color: var(--text-muted); transition: transform var(--dur-fast) var(--ease-out);
}
.chip:active { transform: scale(0.95); }
.chip--muted { border: none; background: var(--accent-soft); color: var(--accent-strong); }
.chip--house { border: none; background: var(--accent); color: white; font-weight: 600; }
.chip--icon { display: flex; align-items: center; justify-content: center; padding: 8px; border: none; border-radius: var(--radius-sm); min-width: 44px; min-height: 44px; }
.chip--icon img { display: block; width: auto; height: 28px; border-radius: 6px; }
.chip--ticket { background: var(--accent-soft); color: var(--accent-strong); border: none; font-weight: 600; cursor: pointer; }
.chip--geocache { background: var(--alert-soft); color: var(--alert); border: none; font-weight: 600; }

.activity-card__ticket {
  margin-top: var(--space-3); padding: var(--space-3);
  background: var(--accent-soft); border-radius: var(--radius-md);
  display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start;
}
.activity-card__ticket-codes { display: flex; flex-wrap: wrap; gap: var(--space-3); width: 100%; }
.activity-card__ticket-img {
  display: block; background: white; padding: var(--space-2);
  border-radius: var(--radius-sm); height: 200px; width: auto; max-width: 100%;
}
.activity-card__ticket-img--barcode { height: 90px; }
.activity-card__ticket-code {
  display: flex; flex-direction: column; gap: 2px;
  background: white; border-radius: var(--radius-sm);
  padding: var(--space-3); width: 100%;
}
.activity-card__ticket-code-label { font-size: var(--text-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
.activity-card__ticket-note {
  font-size: var(--text-sm); color: var(--text); line-height: 1.5;
  background: white; border-radius: var(--radius-sm);
  padding: var(--space-3); width: 100%; box-sizing: border-box;
}
.activity-card__ticket-code-value {
  font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700;
  color: var(--accent-strong); letter-spacing: 0.02em; user-select: all; word-break: break-all;
}
.activity-card__ticket-code-value--sm { font-size: var(--text-base); }
.activity-card__ticket-items { display: flex; flex-wrap: wrap; gap: var(--space-3); width: 100%; }
.activity-card__ticket-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: white; border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  flex: 1 1 calc(50% - var(--space-3)); box-sizing: border-box;
}
.activity-card__ticket-item-label { font-size: var(--text-xs); color: var(--text-muted); font-weight: 600; }
.activity-card__ticket-item .activity-card__ticket-img { width: 100%; height: auto; }

.day-detail--anim-fwd { animation: day-slide-in-fwd var(--dur-spring) var(--ease-out) both; }
.day-detail--anim-back { animation: day-slide-in-back var(--dur-spring) var(--ease-out) both; }
@keyframes day-slide-in-fwd {
  from { opacity: 0; transform: translateX(28px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes day-slide-in-back {
  from { opacity: 0; transform: translateX(-28px); }
  to { opacity: 1; transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .day-detail--anim-fwd, .day-detail--anim-back { animation: none; }
}

.day-pending { display: flex; align-items: center; justify-content: center; min-height: 60vh; }
.day-pending p { font-size: var(--text-2xl); color: var(--accent); }

.dies-stage { margin-bottom: var(--space-6); }
.dies-stage__title { font-size: var(--text-sm); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: var(--space-3); }
.dies-list { display: flex; flex-direction: column; gap: var(--space-3); list-style: none; padding: 0; margin: 0; }
.dies-card {
  position: relative; display: block; height: 148px;
  border-radius: var(--radius-md); overflow: hidden;
  background-color: var(--accent-soft); background-size: cover; background-position: center;
  box-shadow: var(--shadow-sm); color: var(--text); text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-out);
}
.dies-card:active { transform: scale(0.98); }
.dies-card__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,16,14,0.05) 32%, rgba(8,14,12,0.82) 100%);
}
.dies-card--photo { color: #fff; }
.dies-card__num {
  position: absolute; top: var(--space-3); left: var(--space-3); z-index: 1;
  font-size: var(--text-xs); line-height: 1; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  background: var(--bg-elevated); color: var(--text-muted); box-shadow: var(--shadow-sm);
  padding: 4px 9px; border-radius: 999px;
}
.dies-card--photo .dies-card__num {
  background: rgba(0,0,0,0.32); color: #fff; backdrop-filter: blur(4px); box-shadow: none;
}
/* Same alert color as the locked-activity notice in the day detail view,
   so the "don't move this" signal reads consistently across both screens. */
.dies-card__num--locked, .dies-card--photo .dies-card__num--locked {
  background: var(--alert); color: #fff;
}
/* The 🎟️ emoji's own colors (pale confetti/lines) sink into the --alert
   orange behind it. A dark drop-shadow rim keeps it legible without
   changing its shape — unlike text-shadow, `filter` still renders on
   color-font glyphs in every engine that matters here. */
.dies-card__num-icon {
  filter: drop-shadow(0 0 1.5px rgba(0,0,0,0.6)) drop-shadow(0 0 1.5px rgba(0,0,0,0.6));
}
.dies-card__num--today, .dies-card--photo .dies-card__num--today {
  background: var(--accent); color: #fff;
}
.dies-card__body {
  position: static; height: 100%; z-index: 1;
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  padding: var(--space-4);
}
.dies-card--photo .dies-card__body {
  position: absolute; left: 0; right: 0; bottom: 0; height: auto; justify-content: flex-start;
  padding: var(--space-3) var(--space-4);
}
.dies-card__label { font-size: var(--text-xs); line-height: 1; opacity: 0.85; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.dies-card__title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; line-height: 1.2; }
.dies-card__meta { display: flex; align-items: center; gap: var(--space-2); margin-top: 2px; }
.dies-card__emojis { font-size: var(--text-base); opacity: 0.92; }
.dies-card__weather[hidden] { display: none; }
.dies-card__weather { font-size: var(--text-sm); opacity: 0.92; margin-left: auto; white-space: nowrap; }
.dies-card__weather-temp { font-weight: 600; }
/* Large disclosure arrow — used on the Avui hero card, whose photo can
   otherwise read as a static banner rather than a link into the day's
   activity list. Vertically centered on the right edge (a standard
   drill-in position) rather than a top-right circular badge on purpose:
   that spot/style is taken by the prev/next-day nav buttons on the day
   detail view (.day-hero__nav), which mean "switch day", not "open this
   day". The Dies list skips this — it already reads as a list of links,
   so repeating it on all 14 cards would be noise. */
.dies-card__hint {
  position: absolute; top: 50%; right: var(--space-3); z-index: 1;
  transform: translateY(-50%);
  font-size: 44px; font-weight: 700; line-height: 1; color: #fff;
  text-shadow: 0 1px 6px rgba(0,0,0,0.5);
}
/* scroll-margin-top gives the anchor-on-entry scroll (js/views/dies.js) some
   breathing room above the card — without it, scrollIntoView aligns the card
   flush with #view's scrollport edge, ignoring #view's own padding-top
   (regular padding only reserves space at scrollTop 0; a programmatic
   scroll like this collapses it). Uses --safe-top, not a flat --space-4, so
   the card clears the status bar/notch on an installed PWA instead of
   surfacing right under it. */
.dies-card--today { outline: 2px solid var(--accent); outline-offset: 2px; scroll-margin-top: var(--safe-top); }
.dies-card--past { height: 96px; }
.dies-card--past.dies-card--photo { filter: grayscale(1); }
/* .dies-card__body is bottom-anchored absolute (see .dies-card--photo
   .dies-card__body above) and grows upward with its content — on the
   shorter 96px past-card height, a long title wrapping to 2 lines grows
   tall enough to run into the day-number badge pinned at the top instead
   of being pushed clear of it. Past cards already drop the emoji/weather
   meta row for the same reason, so clamp the title to one line too. */
.dies-card--past .dies-card__title {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* margin-top (not padding on .dies-view) is what keeps this off-screen: a
   viewport-relative gap, so it stays below the fold on first landing no
   matter how tall the last stage's card list happens to be, and only
   surfaces once someone scrolls a bit further on purpose. */
.dies-outro {
  margin-top: 18vh;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  text-align: center;
}
.dies-outro__img { width: min(280px, 74%); height: auto; }
.dies-outro__caption {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: var(--text-base); color: var(--text-muted); margin: 0;
}
/* Same illustration on the last day's own page (day-render.js) — it closes
   out real content instead of hiding below a false scroll, so it takes the
   timeline's own section spacing instead of the list easter egg's spacer. */
.dies-outro--day { margin-top: var(--space-6); }

.dies-back { display: inline-block; margin-bottom: var(--space-3); color: var(--accent); font-size: var(--text-sm); }

/* position: fixed, not sticky+negative-margin like a first attempt at this
   had it — pinning it to the viewport instead of #view's own top edge takes
   it out of document flow entirely, so it can never push #dies-day (and the
   hero inside it) down or up by however tall this bar happens to be. A
   sticky element still reserves its flow space even while visually stuck,
   and negative-margin-cancelling that space turned out to interact badly
   with collapsing margins on its neighbours — this sidesteps that class of
   bug rather than chasing it. #view is the only scrolling surface and
   already spans right up to the true top of the screen, so pinning to the
   viewport reads identically to pinning to #view. */
.dies-detail-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-3);
  padding: 0 var(--space-4);
  max-height: 0; overflow: hidden;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: max-height var(--dur-fast) var(--ease-out), padding var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.dies-detail-nav.is-scrolled {
  max-height: calc(64px + env(safe-area-inset-top));
  padding: var(--safe-top) var(--space-4) var(--space-3);
  border-bottom-color: var(--border); box-shadow: var(--shadow-sm);
}
/* --hero-nav-color is set from JS (dies.js) to the same sampled photo colour
   as the status bar's theme-color (js/utils/theme-color.js) — fully opaque
   and without the blur every other day gets, so it reads as the exact same
   flat colour as the status bar above it instead of a lighter, blurred-over
   -content wash of it. */
.dies-detail-nav--hero {
  background: var(--hero-nav-color, var(--bg));
  backdrop-filter: none;
}
.dies-detail-nav--hero.is-scrolled { border-bottom-color: rgba(255,255,255,0.2); }
.dies-detail-nav--hero .dies-back,
.dies-detail-nav--hero .dies-detail-nav__title { color: #fff; }
.dies-detail-nav .dies-back { margin-bottom: 0; flex-shrink: 0; white-space: nowrap; }
.dies-detail-nav__title {
  flex: 1; min-width: 0; text-align: center;
  font-size: var(--text-sm); font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transition: opacity var(--dur-fast) var(--ease-out);
  pointer-events: none;
}
.dies-detail-nav.is-scrolled .dies-detail-nav__title { opacity: 1; }
.dies-daynav { display: flex; gap: var(--space-2); flex-shrink: 0; }
.dies-daynav__btn {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-strong);
  font-size: var(--text-lg); font-weight: 600; line-height: 1;
  transition: transform var(--dur-fast) var(--ease-out);
}
.dies-daynav__btn:active { transform: scale(0.9); }
.dies-daynav__btn--hidden { visibility: hidden; }

.avui-now { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-5); }

.ticket-alert {
  background: var(--alert-soft); border-radius: var(--radius-md);
  padding: var(--space-4); margin-bottom: var(--space-4);
  border: 1px dashed color-mix(in srgb, var(--alert) 35%, transparent);
}
.ticket-alert__title { font-size: var(--text-sm); font-weight: 700; color: var(--alert); }
.ticket-alert__list { list-style: none; padding: 0; margin: var(--space-3) 0 0; display: flex; flex-direction: column; gap: var(--space-3); }
.ticket-alert__item { display: flex; flex-direction: column; gap: 2px; }
.ticket-alert__link {
  display: flex; flex-direction: column; gap: 2px;
  text-decoration: none; color: inherit; margin: calc(var(--space-2) * -1); padding: var(--space-2);
  border-radius: var(--radius-sm); transition: transform var(--dur-fast) var(--ease-out);
}
.ticket-alert__link:active { transform: scale(0.98); }
.ticket-alert__day { font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--alert); opacity: 0.85; }
.ticket-alert__activity { font-size: var(--text-base); font-weight: 600; color: var(--text); }
.ticket-alert__note { font-size: var(--text-sm); color: var(--text-muted); margin: 0 0 0 var(--space-2); }

.weather-strip[hidden] { display: none; }
.weather-strip {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--bg-elevated); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-sm);
  width: 100%; border: none; text-align: left; cursor: pointer;
  font-family: var(--font-body); color: var(--text);
}
.weather-strip__icon { font-size: var(--text-xl); }
.weather-strip__temp { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; }
.weather-strip__range { font-size: var(--text-sm); color: var(--text-muted); margin-left: auto; }
.weather-strip__chev { color: var(--text-muted); font-size: var(--text-base); margin-left: var(--space-1); }

.route-map { background: var(--bg-elevated); border-radius: var(--radius-md); padding: var(--space-4); box-shadow: var(--shadow-sm); }
.route-map__countdown { font-size: var(--text-sm); color: var(--accent-strong); font-weight: 600; margin-bottom: var(--space-3); }
.route-map__link { display: inline-block; font-size: var(--text-sm); font-weight: 600; color: var(--accent); margin-top: var(--space-3); }

.route-stops { display: flex; flex-direction: column; gap: var(--space-3); list-style: none; padding: 0; margin: 0; }
.route-stops__item { display: flex; align-items: baseline; gap: var(--space-2); font-size: var(--text-base); }
.route-stops__num {
  flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-strong);
  font-size: var(--text-xs); font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  transform: translateY(1px);
}
.route-stops__time { color: var(--text-muted); font-size: var(--text-sm); }
.route-stops__title { color: var(--text); }

/* The next activity's row — first in the list, tappable to expand into a
   full card in place. Filled number + coloured time + bold title carry the
   "this one's different" signal instead of a separate line/style. */
.route-stops__item--next { cursor: pointer; }
.route-stops__item--next .route-stops__num { background: var(--accent); color: white; }
.route-stops__item--next .route-stops__time { color: var(--accent-strong); font-weight: 600; }
.route-stops__item--next .route-stops__title { font-weight: 600; flex: 1; }
.route-stops__chev { color: var(--accent); font-size: var(--text-sm); }

.day-timeline--highlight { margin-bottom: 0; }
.activity-card--highlight { border-left: 4px solid var(--accent); border-radius: 0 var(--radius-md) var(--radius-md) 0; position: relative; }
.activity-card__badge {
  position: absolute; top: var(--space-4); right: var(--space-4);
  font-size: var(--text-xs); font-weight: 600; padding: 3px var(--space-2); border-radius: 999px;
  background: var(--accent); color: white;
}

/* activity.locked: tied to a real, non-reprogrammable booking — flagged
   distinctly (alert color) so it never gets silently moved while replanning. */
.activity-card--locked { border-left: 4px solid var(--alert); border-radius: 0 var(--radius-md) var(--radius-md) 0; }

/* One row for every status pill (needs-ticket / tide) instead of a stacked
   paragraph each. Tapping needs-ticket expands just that pill to full width
   for the full note; closed pills keep wrapping shoulder to shoulder. */
.activity-card__status { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.activity-card__status-item { width: fit-content; }
.activity-card__status-item[open] { flex-basis: 100%; width: auto; }
.activity-card__status-item summary {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer; list-style: none;
}
.activity-card__status-item summary::-webkit-details-marker { display: none; }
.activity-card__status-reason {
  font-size: var(--text-sm); color: var(--alert);
  background: var(--alert-soft); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); margin-top: var(--space-2);
}
.chip--ticket-needed { background: var(--alert-soft); color: var(--alert); border: none; font-weight: 600; }
.chip--tide { background: var(--accent-soft); color: var(--accent-strong); border: none; font-weight: 600; }

.next-up-expanded { cursor: pointer; }

/* "Valoracions": stars + free text per activity, once it has actually
   happened — see isActivityRatable in js/views/day-render.js. */
.activity-notes { margin-top: var(--space-3); border-top: 1px dashed var(--border); padding-top: var(--space-3); }

/* Whole-day valoració, shown once under the timeline for a fully-past day. */
.day-notes {
  margin-top: var(--space-4); background: var(--bg-elevated); border-radius: var(--radius-md);
  padding: var(--space-4); box-shadow: var(--shadow-sm);
}
.activity-notes__list { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-2); }
.activity-notes__item { background: var(--accent-soft); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); }
.activity-notes__item-head { display: flex; align-items: center; gap: var(--space-2); }
.activity-notes__item-stars { color: var(--accent-strong); font-size: var(--text-sm); letter-spacing: 1px; }
.activity-notes__item-text { font-size: var(--text-sm); color: var(--text); margin-top: var(--space-1); white-space: pre-wrap; }
.activity-notes__confirm-text { font-size: var(--text-sm); }
.activity-notes__confirm-actions { display: flex; gap: var(--space-2); margin-top: var(--space-2); }
.activity-notes__confirm-actions button { flex: 1; padding: var(--space-2); border-radius: var(--radius-sm); font-weight: 600; text-align: center; border: none; }
.activity-notes__cancel-delete { background: var(--bg-elevated); color: var(--text-muted); }
.activity-notes__confirm-delete { background: var(--alert); color: white; }
.activity-notes__edit, .activity-notes__delete {
  display: flex; align-items: center; justify-content: center; min-width: 36px; min-height: 36px;
  border: none; background: none; color: var(--text-muted); font-size: var(--text-sm); line-height: 1;
}
.activity-notes__edit { margin-left: auto; }
.activity-notes__edit:active { color: var(--accent-strong); }
.activity-notes__delete:active { color: var(--alert); }

.activity-notes__heading { font-size: var(--text-base); font-weight: 600; color: var(--text); margin-bottom: var(--space-2); }

/* Deliberately separate from .activity-notes__heading (see the comment on
   renderNotesPanel in day-render.js) — this is the one, unambiguous "add a
   new one" action, so it keeps explicit "+ Afegeix" wording and accent
   color instead of doubling as the section title. */
.activity-notes__add-btn {
  display: flex; align-items: center; min-height: 44px; border: none; background: none; color: var(--accent-strong);
  font-size: var(--text-sm); font-weight: 700; padding: var(--space-2) 0; text-align: left;
}
.activity-notes__add-btn[hidden] { display: none; }
.activity-notes__add-btn:active { opacity: 0.7; }

.activity-notes__form { display: flex; flex-direction: column; gap: var(--space-3); }
.activity-notes__form[hidden] { display: none; }
.activity-notes__authors { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip--author { background: var(--bg); cursor: pointer; }
.chip--author.is-selected { border-color: var(--accent); background: var(--accent); color: white; font-weight: 600; }

.activity-notes__stars { display: flex; gap: var(--space-1); }
.activity-notes__star {
  border: none; background: none; font-size: var(--text-xl); line-height: 1;
  color: var(--text-muted); padding: 0 2px; min-width: 32px; min-height: 32px;
}
.activity-notes__star.is-filled { color: var(--accent-strong); }

.activity-notes__text {
  font: inherit; font-size: var(--text-sm); color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  resize: vertical;
}

.activity-notes__form-actions { display: flex; justify-content: flex-end; gap: var(--space-3); }
.activity-notes__cancel { border: none; background: none; color: var(--text-muted); font-size: var(--text-sm); }
.activity-notes__save {
  border: none; background: var(--accent); color: white; font-weight: 600;
  font-size: var(--text-sm); padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
}
.activity-notes__save:active { transform: scale(0.97); }
