/* === Section-specific content styles === */

/* POTD section */
.potd-entry {
  margin-bottom: var(--space-2xl);
}

.potd-entry__date {
  font-family: var(--font-shell);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
  text-transform: uppercase;
  margin-bottom: var(--space-sm);
}

.potd-entry__title {
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: var(--space-xs);
}

.potd-entry__author {
  font-style: italic;
  color: var(--fg-muted);
  margin-bottom: var(--space-lg);
}

.potd-entry__text {
  line-height: 1.8;
  font-size: 1.1rem;
}

.potd-line {
  padding-left: 1.6em;
  text-indent: -1.6em;
}

/* Blog section */
.blog-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-shell);
  font-size: 0.9rem;
  color: var(--red);
  text-decoration: none;
  padding: var(--space-md) var(--space-lg);
  border: 2px solid var(--red);
  transition: background var(--duration-fast), color var(--duration-fast);
}

.blog-link:hover {
  background: var(--red);
  color: var(--bg-content);
}

.blog-link::after {
  content: '\2192'; /* right arrow */
}

/* === Favorites slot machine (About page) === */

.favorites-slot {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-top: var(--space-2xl);
  padding-top: var(--space-xl);
  border-top: 1px dashed rgba(44, 37, 37, 0.18);
  clear: both;
}

.favorites-slot__viewport {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 12em;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.12) 12%,
    rgba(0, 0, 0, 0.45) 30%,
    rgba(0, 0, 0, 1) 50%,
    rgba(0, 0, 0, 0.45) 70%,
    rgba(0, 0, 0, 0.12) 88%,
    rgba(0, 0, 0, 0) 100%
  );
          mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.12) 12%,
    rgba(0, 0, 0, 0.45) 30%,
    rgba(0, 0, 0, 1) 50%,
    rgba(0, 0, 0, 0.45) 70%,
    rgba(0, 0, 0, 0.12) 88%,
    rgba(0, 0, 0, 0) 100%
  );
}

.favorites-slot__reel {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.favorites-slot__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4em;
  padding: 0.45em 0.1em;
  font-size: 1.25rem;
  line-height: 1.5;
  font-style: italic;
  color: var(--fg);
}

.slot-prefix {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* The "thing" sits beside the prefix when there's room, otherwise wraps
   onto its own line — wrapped lines then hang from the start of the thing. */
.slot-thing {
  flex: 1 1 auto;
  min-width: 40%;
  -webkit-hyphens: auto;
          hyphens: auto;
  overflow-wrap: break-word;
}

.slot-lead {
  color: var(--fg-muted);
  font-style: italic;
}

.slot-category,
.slot-title {
  font-style: normal;
  font-weight: 700;
  color: var(--fg);
}

/* Linked title takes on the prose-link look (red, no underline, hover orange).
   Inherits color/transition from .content-pane__inner a. Only the centered row
   is clickable — viewport itself disables pointer events. */
.slot-link {
  font-style: normal;
}

/* Re-enable pointer events on the settled center row so its text is
   selectable and any link inside is clickable. Off-center rows remain inert
   (viewport sets pointer-events: none) so the user can't grab text mid-spin
   or click links that aren't the current pick. */
.favorites-slot__row.is-centered {
  pointer-events: auto;
}

.favorites-slot__reroll {
  flex: 0 0 auto;
  width: 2.4em;
  height: 2.4em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--red);
  border: 2px solid var(--red);
  border-radius: 999px;
  font-family: var(--font-shell);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

.favorites-slot__reroll:hover {
  background: var(--red);
  color: var(--bg-content);
  transform: rotate(-60deg);
}

.favorites-slot__reroll:active {
  transform: rotate(-180deg) scale(0.94);
}

.favorites-slot__reroll span {
  display: inline-block;
}

/* === Life Calendar ====================================================== */

/* When the life calendar is active, the content pane fills the viewport
   without scrolling — the annotations list scrolls internally. min-height:0
   on the flex chain stops the panel's content from forcing the layout
   taller than the viewport. */
.content-pane:has(.lifecal) {
  overflow: hidden;
}
.content-pane__inner:has(.lifecal) {
  max-width: none;
  padding: var(--space-lg) var(--space-xl);
  height: 100%;
  max-height: 100%;
  min-height: 0;
  overflow: hidden;
}

.lifecal {
  display: flex;
  flex-direction: column;
  height: 100%;
  max-height: 100%;
  min-height: 0;
  overflow: hidden;
  font-family: var(--font-content);
  color: var(--fg);
  font-variant-numeric: lining-nums tabular-nums;
}

.lifecal__head {
  flex: 0 0 auto;
  margin-bottom: var(--space-md);
}

.lifecal__title {
  font-family: var(--font-content);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.1;
  margin: 0 0 0.2em 0;
  color: var(--fg);
}

.lifecal__sub {
  font-family: var(--font-shell);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--fg-muted);
  margin: 0;
}

.lifecal__body {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-height: 0;
}

/* ── main column: grid + gutters ─────────────────────────────────────── */

.lifecal__main {
  flex: 1 1 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 0;
  /* Right gutter for era labels; left gutter for decade numbers. The grid
     is centered between them via the flex container. */
  padding: 0.4em 7.5rem 0.4em 1.8rem;
  /* `size` exposes both axes via cqw/cqh to children — used by grid-wrap
     to compute the largest 52:90 box that fits without distortion. */
  container-type: size;
}

.lifecal__grid-wrap {
  position: relative;
  /* Largest 52:--rows box that fits inside the padded main container.
     With just aspect-ratio + height:100%, height wins and the box
     stretches beyond aspect — this min() pair forces the smaller of the
     two dimensions and lets the other follow the ratio. The row count
     comes from JS (AGI pillèdness mode), defaulting to 80. */
  --rows: 80;
  aspect-ratio: 52 / var(--rows);
  width:  min(100cqw, calc(100cqh * 52 / var(--rows)));
  height: min(100cqh, calc(100cqw * var(--rows) / 52));
  overflow: visible;
}

/* Background layer: era bands + decade lines + lifeexp line. Behind grid. */
.lifecal__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.lifecal__era {
  position: absolute;
  left: 0;
  right: 0;
  background: var(--era-bg, transparent);
  opacity: 0.09;
}
.lifecal__era--yellow { --era-bg: var(--yellow); }
.lifecal__era--orange { --era-bg: var(--orange); }
.lifecal__era--green  { --era-bg: var(--green);  }
.lifecal__era--cyan   { --era-bg: var(--cyan);   }
.lifecal__era--red    { --era-bg: var(--red);    }
.lifecal__era--purple { --era-bg: var(--purple); }

.lifecal__decade-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dashed rgba(44, 37, 37, 0.18);
  pointer-events: none;
}

/* 5-year tick — paper-colored stripe drawn over the grid (in the labels
   layer, z-index 2) so it visually carves a small gap into the cells
   every 5 rows. Slightly taller at decade boundaries so they read as
   "stronger" markers without needing a separate dashed line. */
.lifecal__year-tick {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--bg-content);
  transform: translateY(-50%);
  pointer-events: none;
}
.lifecal__year-tick--decade {
  height: 3px;
}

.lifecal__lifeexp-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dotted rgba(44, 37, 37, 0.5);
  pointer-events: none;
}

/* The grid itself */
.lifecal__grid {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(52, 1fr);
  /* --rows inherits from .lifecal__grid-wrap. */
  grid-template-rows: repeat(var(--rows, 80), 1fr);
  gap: 1px;
  z-index: 1;
}

.lifecal__cell {
  background: rgba(44, 37, 37, 0.05);
  border-radius: 1px;
  cursor: default;
  position: relative;
  /* AGI fade band fades the whole cell to transparent. Defaults to 1.
     Lived cells multiply this with --cell-alpha (jitter) below. */
  opacity: var(--fade, 1);
  /* Isolate each cell's layout/paint so hovering one doesn't dirty its
     neighbours. With ~4k cells, this is the single biggest perf win. */
  contain: layout style paint;
  /* No transition — with ~4k cells and rapid mouse movement across the
     grid, animating every transform was making hover feel laggy. Snap. */
}

.lifecal__cell:hover {
  transform: scale(1.8);
  z-index: 5;
  background: var(--fg);
}

.lifecal__cell--lived {
  background: color-mix(in srgb, var(--era, var(--fg-muted)) 65%, var(--bg-content));
  /* Compound the per-cell jitter with the AGI fade so older lived weeks
     (in cases where lived extends past the AGI horizon) fade with the
     rest of the band rather than ignoring it. */
  opacity: calc(var(--cell-alpha, 1) * var(--fade, 1));
  /* mix-blend-mode dropped: the per-cell stacking-context cost across
     1.3k cells was the heaviest remaining hover/scroll expense. The
     paper texture still shows through via per-cell opacity jitter. */
}

.lifecal__cell--current {
  /* Partial fill: solid dark fg from 0..fill, near-white after.
     Dark vs the warm pale paper makes it the most visible cell on the
     grid even before the blink. */
  background: linear-gradient(
    to right,
    var(--fg) calc(var(--fill, 0.5) * 100%),
    var(--bg-content) calc(var(--fill, 0.5) * 100%)
  );
  animation: lifecal-blink 1.0s steps(2, end) infinite;
  opacity: 1 !important;
  mix-blend-mode: normal;
  transform: scale(1.7);
  z-index: 10;
  will-change: opacity;
  /* Halo: bg-content gap then dark ring, separates the cell visually
     from neighbors so the scaled-up box reads as one chunky marker. */
  box-shadow:
    0 0 0 1.5px var(--bg-content),
    0 0 0 2.5px var(--fg),
    0 0 6px rgba(44, 37, 37, 0.5);
}

@keyframes lifecal-blink {
  0%   { opacity: 1; }
  50%  { opacity: 0.15; }
  100% { opacity: 1; }
}

/* Annotated cells: thin colored ring matching category. */
.lifecal__cell--annotated {
  box-shadow: inset 0 0 0 1px var(--cat-color, var(--fg-muted));
}
.lifecal__cell--cat-literature  { --cat-color: var(--purple); }
.lifecal__cell--cat-music       { --cat-color: var(--orange); }
.lifecal__cell--cat-science     { --cat-color: var(--cyan); }
.lifecal__cell--cat-philosophy  { --cat-color: var(--yellow); }
.lifecal__cell--cat-ai          { --cat-color: var(--red); }
.lifecal__cell--cat-personal    { --cat-color: var(--green); }

.lifecal__cell--estimate {
  /* AI forecast cells (Automated Coder, ASI). Static red ring + soft glow.
     No animation — the breathing was triggering box-shadow repaints across
     the whole cell area on every frame, making hover feel sluggish. */
  background: color-mix(in srgb, var(--red) 32%, var(--bg-content));
  box-shadow:
    inset 0 0 0 0.5px var(--bg-content),
    0 0 0 1.4px var(--red),
    0 0 8px rgba(253, 104, 131, 0.7);
  transform: scale(1.55);
  z-index: 4;
  will-change: transform;
}

.lifecal__cell.is-card-hovered {
  transform: scale(2.2);
  z-index: 6;
  box-shadow:
    inset 0 0 0 1px var(--cat-color, var(--fg)),
    0 0 6px var(--cat-color, var(--fg));
}

/* Labels layer: decade nums (left), era labels (right), lifeexp label.
   Sits in the gutters; its container is overlay-sized but its children
   spill into the parent .lifecal__main padding. */
.lifecal__labels {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.lifecal__decade-num {
  position: absolute;
  left: -1.6rem;
  transform: translateY(-50%);
  font-family: var(--font-shell);
  font-size: 0.72rem;
  color: var(--fg-faint);
  letter-spacing: 0.04em;
  line-height: 1;
}

.lifecal__era-label {
  position: absolute;
  left: calc(100% + 0.6rem);
  transform: translateY(-50%);
  font-family: var(--font-content);
  font-style: italic;
  font-size: 0.95rem;
  color: var(--fg-muted);
  white-space: nowrap;
  line-height: 1;
}

/* Emoji don't have an italic glyph in the system emoji font, so the
   browser fakes one via an oblique transform — pictographs lean and
   look broken. Reset the inheritance for these spans only. */
.lifecal__emoji {
  font-style: normal;
  font-variant-emoji: emoji;
  display: inline-block;
}

/* AI estimate gutter labels — same right gutter as era labels but in
   monospace and red, to mirror the glow on the cells. */
.lifecal__estimate-label {
  position: absolute;
  left: calc(100% + 0.6rem);
  transform: translateY(-50%);
  font-family: var(--font-shell);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red);
  white-space: nowrap;
  line-height: 1;
}

.lifecal__lifeexp-label {
  position: absolute;
  right: 0.4rem;
  transform: translateY(calc(-100% - 2px));
  font-family: var(--font-shell);
  font-size: 0.6rem;
  font-style: italic;
  color: var(--fg-faint);
  letter-spacing: 0.05em;
}

/* Tooltip */
.lifecal__tooltip {
  position: absolute;
  z-index: 20;
  pointer-events: none;
  background: var(--fg);
  color: var(--bg-content);
  padding: 0.5em 0.7em;
  border-radius: 2px;
  box-shadow: 0 4px 12px rgba(44, 37, 37, 0.25);
  font-family: var(--font-shell);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  line-height: 1.3;
  /* Allow annotation titles to wrap, but keep simple week tooltips tight. */
  white-space: normal;
  max-width: 18rem;
  width: max-content;
}
.lifecal__tt-head {
  font-weight: 700;
  margin-bottom: 0.15em;
}
.lifecal__tt-range {
  opacity: 0.7;
  font-style: italic;
}
/* Annotation block — sits on top of the week/range, set apart by a hairline. */
.lifecal__tt-ann {
  padding-bottom: 0.5em;
  margin-bottom: 0.5em;
  border-bottom: 1px solid rgba(250, 246, 240, 0.18);
}
.lifecal__tt-ann-cat {
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.65;
  margin-bottom: 0.2em;
}
.lifecal__tt-ann-est {
  opacity: 0.6;
}
.lifecal__tt-ann-title {
  font-family: var(--font-content);
  font-size: 0.95rem;
  font-style: italic;
  font-weight: 700;
  line-height: 1.25;
  margin-bottom: 0.15em;
}
.lifecal__tt-ann-sub {
  font-family: var(--font-content);
  font-style: italic;
  font-size: 0.78rem;
  opacity: 0.75;
  line-height: 1.3;
}

/* ── side panel ──────────────────────────────────────────────────────── */

/* Stats card + No-u form, side-by-side in a single row above the calendar.
   `order: -1` lifts the panel above .lifecal__main without reshuffling the
   HTML (DOM order keeps the calendar as primary content). The flex chain
   between stats/nou divides whatever width the content pane gives us. */
.lifecal__panel {
  flex: 0 0 auto;
  display: flex;
  flex-direction: row;
  gap: var(--space-md);
  align-items: stretch;
  order: -1;
}

.lifecal__stats {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-md);
  border-left: 3px solid var(--red);
  background: rgba(253, 104, 131, 0.05);
}
.lifecal__stat-line {
  font-size: 1rem;
  line-height: 1.4;
}
.lifecal__stat-num {
  font-family: var(--font-shell);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--red);
  font-variant-numeric: tabular-nums lining-nums;
}
.lifecal__stat-pct,
.lifecal__stat-sub {
  font-style: italic;
  color: var(--fg-muted);
  font-size: 0.92rem;
  margin-top: 0.25em;
}

/* AGI pillèdness — third card in the panel row. Yellow accent so the
   three cards make a stoplight (yellow / red / cyan) reading L→R. */
.lifecal__agi {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-md);
  border-left: 3px solid var(--yellow);
  background: rgba(249, 204, 108, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}
.lifecal__agi-lead {
  font-family: var(--font-shell);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}
/* The grave on the è is a literal Unicode character in the markup; this
   span exists in case we ever want to color or style the accent
   separately. Today it just inherits — kept as a hook. */
.lifecal__agi-lead-accent {
  font-style: normal;
}
.lifecal__agi-select {
  font-family: var(--font-shell);
  font-size: 0.85rem;
  padding: 0.3em 0.4em;
  border: 1px solid var(--fg-faint);
  background: var(--bg-content);
  color: var(--fg);
  cursor: pointer;
  width: 100%;
  min-width: 0;
}

/* No u form — mirrors the stats card: same padding, same accent-bar
   pattern but in cyan. Sits to the right of stats in the panel row. */
.lifecal__nou {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-md);
  border-left: 3px solid var(--cyan);
  background: rgba(133, 218, 204, 0.06);
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}
.lifecal__nou-lead {
  font-family: var(--font-shell);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}
.lifecal__nou-row {
  display: flex;
  gap: 0.4em;
  align-items: center;
}
.lifecal__nou-input {
  flex: 1 1 auto;
  font-family: var(--font-shell);
  font-size: 0.85rem;
  padding: 0.3em 0.4em;
  border: 1px solid var(--fg-faint);
  background: var(--bg-content);
  color: var(--fg);
  min-width: 0;
}
.lifecal__nou-btn,
.lifecal__nou-reset {
  font-family: var(--font-shell);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  padding: 0.4em 0.8em;
  border: 1px solid var(--cyan);
  background: transparent;
  color: color-mix(in srgb, var(--cyan) 70%, var(--fg));
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.lifecal__nou-btn:hover,
.lifecal__nou-reset:hover {
  background: var(--cyan);
  color: var(--bg-content);
}
.lifecal__nou-reset {
  border-color: var(--fg-faint);
  color: var(--fg-muted);
}
.lifecal__nou-reset:hover {
  background: var(--fg-muted);
  color: var(--bg-content);
}

/* ── Birthday easter egg overlay ────────────────────────────────────── */

.lifecal__bday-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(44, 37, 37, 0.55);
  backdrop-filter: blur(2px);
  animation: lifecal-fade-in 0.4s ease-out;
}

/* Explicit `display: flex` above shadows the UA [hidden] rule, so we have
   to re-assert it. Without this, the overlay is permanently visible. */
.lifecal__bday-overlay[hidden] { display: none; }

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

.lifecal__bday-card {
  background: var(--bg-content);
  padding: var(--space-2xl) var(--space-xl);
  max-width: 32rem;
  text-align: center;
  box-shadow: 0 12px 60px rgba(44, 37, 37, 0.4);
  border: 1px solid rgba(44, 37, 37, 0.1);
  position: relative;
  z-index: 1;
}
.lifecal__bday-cake {
  font-size: 3rem;
  margin-bottom: var(--space-sm);
  animation: lifecal-cake-bob 1.4s ease-in-out infinite;
}
@keyframes lifecal-cake-bob {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-8px) rotate(3deg); }
}
.lifecal__bday-shout {
  font-family: var(--font-shell);
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--red);
  margin-bottom: var(--space-md);
}
.lifecal__bday-quote {
  font-family: var(--font-content);
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--fg);
  margin-bottom: var(--space-lg);
}
.lifecal__bday-attr {
  font-style: normal;
  font-family: var(--font-shell);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: 0.4em;
}
.lifecal__bday-dismiss {
  font-family: var(--font-shell);
  font-size: 0.85rem;
  padding: 0.5em 1.2em;
  background: transparent;
  border: 1px solid var(--fg);
  color: var(--fg);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.lifecal__bday-dismiss:hover {
  background: var(--fg);
  color: var(--bg-content);
}

/* Confetti */
.lifecal__bday-confetti {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}
.lifecal__confetti-piece {
  position: absolute;
  top: -20px;
  width: 8px;
  height: 14px;
  border-radius: 1px;
  animation: lifecal-confetti-fall linear forwards;
  opacity: 0.85;
}
.lifecal__confetti-piece--red    { background: var(--red); }
.lifecal__confetti-piece--orange { background: var(--orange); }
.lifecal__confetti-piece--yellow { background: var(--yellow); }
.lifecal__confetti-piece--green  { background: var(--green); }
.lifecal__confetti-piece--cyan   { background: var(--cyan); }
.lifecal__confetti-piece--purple { background: var(--purple); }
@keyframes lifecal-confetti-fall {
  0%   { transform: translateY(0) rotate(0deg); }
  100% { transform: translateY(110vh) rotate(720deg); }
}
