/* Crude on purpose — content loop first, §7 design direction later. */
* { box-sizing: border-box; }
body {
  font-family: Georgia, 'Times New Roman', serif;
  max-width: 760px;
  margin: 0 auto;
  /* env(safe-area-inset-*) only matters standalone (viewport-fit=cover) —
     content can otherwise sit under the status bar / rounded corners. */
  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));
  color: #201c17;
  background: #fbf8f3;
  line-height: 1.6;
}

/* --- public site identity: a weekly-music-press dateline ---
   Scoped to :not(.admin-page) — the admin dashboard keeps its own quieter
   palette untouched; these tokens and overrides only ever reach index.html. */
body:not(.admin-page) {
  --bg: #ede7da;         /* newsprint */
  --sleeve: #f6f1e4;     /* card / sleeve surface */
  --ink: #1c1712;        /* body text */
  --ink-faded: #6b6152;  /* meta / secondary text — 4.9:1 against --bg, passes WCAG AA */
  --hairline: #d9d0be;   /* rules + borders */
  --accent: #b23a2e;     /* masthead red — tags, links */
  --today: #2a4d6e;      /* slate blue — today's card, 8.8:1 with white text */
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-optical-sizing: auto;
  color: var(--ink);
  background: var(--bg);
}

header { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem; }
/* Child combinator, not descendant — #article has its own inner <header
   class="article-head">, and a bare "header" selector was matching that too,
   drawing the masthead's rule straight across the floated cover image. */
body:not(.admin-page) > header {
  position: relative;
  border-bottom: 3px solid var(--ink);
  padding-bottom: 0.85rem;
  margin-bottom: 1.8rem;
}
body:not(.admin-page) > header::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -6px;
  height: 2px; background: var(--accent);
}
#fullscreen-btn {
  margin-left: auto;
  font-size: 1.2rem;
  line-height: 1;
  background: none;
  border: 1px solid #e8e1d5;
  border-radius: 6px;
  padding: 0.35rem 0.55rem;
  color: #6b5f4e;
  cursor: pointer;
}
#fullscreen-btn:hover { background: #f1ebe0; }
#fullscreen-btn.active { background: #e8e1d5; }
body:not(.admin-page) #fullscreen-btn { border-color: var(--hairline); color: var(--ink-faded); }
body:not(.admin-page) #fullscreen-btn:hover { background: var(--sleeve); }
body:not(.admin-page) #fullscreen-btn.active { background: var(--hairline); }
#account-line { margin-left: auto; display: flex; align-items: center; gap: 0.6rem; font-family: system-ui, sans-serif; font-size: 0.8rem; color: #6b5f4e; }
#account-line .hint:empty { display: none; }
h1 { margin: 0; font-size: 1.7rem; cursor: pointer; }
body:not(.admin-page) h1 {
  font-family: 'Anton', sans-serif;
  font-size: 1.9rem;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  color: var(--ink);
}

.section-label { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.06em; color: #9a8d7a; margin: 2rem 0 0.6rem; font-family: system-ui, sans-serif; }

.card { display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid #e8e1d5; cursor: pointer; }
.card img { width: 96px; height: 96px; border-radius: 6px; object-fit: cover; }
.card h2 { margin: 0 0 0.2rem; font-size: 1.15rem; }
.card .dek { margin: 0 0 0.3rem; color: #4d453a; }
.card .meta { font-family: system-ui, sans-serif; font-size: 0.75rem; color: #9a8d7a; }
.card .reason { font-family: system-ui, sans-serif; font-size: 0.78rem; color: #8a5a2b; margin-top: 0.25rem; }
.empty { color: #9a8d7a; font-family: system-ui, sans-serif; font-size: 0.9rem; padding: 2rem 0; }

.today-card { border: 1px solid #e8e1d5; border-radius: 10px; padding: 1.2rem; background: #fff; }
.today-card img { width: 140px; height: 140px; }
.today-card h2 { font-size: 1.4rem; }

/* --- home: week calendar strip + scroll-driven archive --- */
#archive-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.2rem 0.1rem 0.6rem; font-family: system-ui, sans-serif;
}
.archive-title { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; color: #9a8d7a; }
body:not(.admin-page) .archive-title {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.14em; color: var(--ink-faded);
}
#archive-toggle-btn {
  width: 2rem; height: 2rem; border-radius: 50%; border: 1px solid #6b5f4e; background: #fff;
  cursor: pointer; font-size: 0.9rem; display: flex; align-items: center; justify-content: center;
  transition: transform 0.3s; color: #201c17; flex-shrink: 0;
}
#archive-toggle-btn.open { transform: rotate(180deg); }
body:not(.admin-page) #archive-toggle-btn { border-color: var(--ink); background: var(--sleeve); color: var(--ink); }
/* clip on the block axis, visible on the inline one. The archive's whole
   mechanic is an animated height, so vertical clipping is load-bearing — but
   `overflow: hidden` clips both axes, and the hovered sleeve grows wider than
   its card, so the first and last card of every week row had their cover,
   border and glow sliced off at the viewport edge.
   `clip` rather than `hidden` is what makes this possible: `visible` on one
   axis is forced to `auto` when the other is `hidden`, which would have
   produced a scrollbar, but it survives next to `clip`. */
#archive-viewport { overflow-x: visible; overflow-y: clip; height: 0; }
#archive-inner { display: flex; flex-direction: column; will-change: transform; }
.month-header {
  font-family: system-ui, sans-serif; font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: 0.06em; color: #9a8d7a; margin: 1rem 0 0.4rem;
}
.month-header:first-child { margin-top: 0.2rem; }
body:not(.admin-page) .month-header {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.68rem; letter-spacing: 0.1em; color: var(--ink-faded);
  border-top: 1px solid var(--hairline); padding-top: 0.6rem;
}
body:not(.admin-page) .month-header:first-child { border-top: none; padding-top: 0; }

.week-row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.5rem; margin-bottom: 0.5rem; }
.day-box {
  display: flex; flex-direction: column; align-items: center;
  /* 0.9rem, not the 0.3rem this started at, because the hover effect below
     needs somewhere to happen: the group shrinks toward its own centre, which
     walks both labels straight into the cover while the cover is growing the
     other way. At 0.3rem the two met 7px inside each label and sliced the
     glyphs. This is the clearance that buys. */
  gap: 0.9rem;
  padding: 0.3rem 0.2rem 0.4rem; border-radius: 8px;
  background: #f0ebe1; border: 1px solid #e8e1d5;
}
.day-box.revealed { cursor: pointer; }
.day-box .day-name {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.05em; color: #9a8d7a;
  font-family: system-ui, sans-serif;
}
.day-box .day-cover {
  width: 100%; aspect-ratio: 1 / 1; border-radius: 6px; overflow: hidden;
  background: #e2dbcb; background-size: cover; background-position: center;
  background-repeat: no-repeat; background-clip: padding-box;
  display: flex; align-items: center; justify-content: center;
}
.day-box .day-icon { font-size: 1.4rem; opacity: 0.75; }
.day-box .theme-name {
  font-size: 0.7rem; color: #6b5f4e; text-align: center; line-height: 1.2;
  font-family: system-ui, sans-serif;
}
.day-box.today { outline: 2px solid #8a5a2b; outline-offset: -2px; }
.day-box.empty { opacity: 0.45; }
body:not(.admin-page) .day-box {
  background: var(--sleeve); border-color: var(--hairline); border-radius: 5px;
}
/* current week = live picks, styled apart from the archive's cream cards:
   white by default. .today marks today's calendar slot (blue); .selected
   marks whichever day's article is currently loaded (black) and — since
   it's declared after .today at the same specificity — wins when a day is
   both, i.e. today's own pick is the one currently open. */
/* :where() so the #id scoping doesn't out-rank .selected/.today below on
   specificity (an ID beats any number of classes) — it should only narrow
   *which* boxes this matches, not force a win regardless of source order. */
body:not(.admin-page) :where(#current-week-row) .day-box:not(.today) { background-color: #fff; }
body:not(.admin-page) .day-box.today {
  background-color: var(--today);
  border-color: var(--today);
  outline: none;
}
body:not(.admin-page) .day-box.today .day-name,
body:not(.admin-page) .day-box.today .theme-name { color: #fff; }
/* border-color, not border: none — a width change (1px -> 0) shifts the
   padding-box that background-size:cover scales against, so the cover
   visibly rescaled for an instant on every state switch. Same width, just
   transparent, keeps the box geometry — and the image — perfectly still. */
body:not(.admin-page) .day-box.today .day-cover { background-color: rgba(255,255,255,0.12); border-color: transparent; }
body:not(.admin-page) .day-box.selected {
  background-color: var(--ink);
  border-color: var(--ink);
}
body:not(.admin-page) .day-box.selected .day-name,
body:not(.admin-page) .day-box.selected .theme-name { color: #fff; }
body:not(.admin-page) .day-box.selected .day-cover { background-color: rgba(255,255,255,0.12); border-color: transparent; }
body:not(.admin-page) .day-box .day-name {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500; letter-spacing: 0.07em; color: var(--ink-faded);
}
/* background-color, not the "background" shorthand — the shorthand resets
   background-size/position too, which un-does the cover/center fit above
   and left day covers showing an unscaled top-left sliver of the artwork. */
body:not(.admin-page) .day-box .day-cover { background-color: var(--bg); border: 1px solid var(--hairline); }
body:not(.admin-page) .day-box .theme-name {
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.76rem; font-weight: 700; color: var(--ink-faded);
}

/* Hover: the card steps back, the sleeve steps forward.
   Scaling the .day-box moves the whole group — surface, border and both
   labels — as one object, which is the point: the labels drift toward the
   card's centre as they shrink, the way a receding thing does. Scaling each
   label on its own would shrink them in place and read as three separate
   twitches instead of one card pulling back.
   Only .revealed boxes animate. They're the ones with cover art and a
   cursor:pointer, so the motion doubles as the click affordance — a
   placeholder or an empty day inviting a click it won't honour is worse
   than no animation at all. */
/* An unregistered custom property is an untyped token, so the browser cannot
   interpolate it: on mouse-out --px/--py vanished and the sheen's gradient lost
   its `at` clause outright, teleporting the highlight to the centre on the
   first frame while the layer was still 83% opaque — it faded from a place the
   pointer had never been. Registering them gives the browser a type to
   interpolate, so the highlight now travels back to rest instead of jumping
   there. Baseline across all three engines since July 2024.
   inherits: true because they are set on .day-box and read two levels down. */
@property --px { syntax: '<number>'; initial-value: 0; inherits: true; }
@property --py { syntax: '<number>'; initial-value: 0; inherits: true; }

.day-box.revealed {
  --recede: 0.85;               /* card group: 15% smaller, as asked */
  --advance: 1.1;               /* cover: 10% bigger than it sits at rest */
  /* What the cover's own transform has to be to land at --advance from inside
     a group shrunk to --recede. Named once because the captions size
     themselves off the same number. */
  --cover-scale: calc(var(--advance) / var(--recede));
  /* ease-out, not ease-in-out: the motion should leave the instant the cursor
     lands and settle into place, rather than easing in off a pause. */
  --hover-ease: 240ms ease-out;
  position: relative;
  transform: scale(1);
  /* The pointer vars ease on the same clock as the card, so when the cursor
     leaves, the sheen and the lit rim drift home while the card settles. */
  transition: transform var(--hover-ease), --px var(--hover-ease), --py var(--hover-ease);
}
/* Hover hit area, and the reason it has to exist: the card shrinks 15% on
   hover, which can move its own edge out from under the pointer that triggered
   it. The pointer then leaves, the card grows back, and it re-enters — a
   flicker loop, measured at 5 state flips in under a second. It only bites near
   the corners; along the sides the enlarged cover overhangs the card and keeps
   the pointer over a descendant, which is enough to hold :hover.
   This pseudo-element pins the hit area to the card's un-hovered footprint by
   counter-scaling the shrink exactly, so once the pointer is on the card it
   stays on it. Transparent, and no separate event target — pseudo-elements
   hit-test as their originating element, so the click still lands on .day-box.
   Not transitioned: it must reach full size on the first frame, otherwise it
   is still shrinking while the pointer is escaping. */
.day-box.revealed::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
}
@media (hover: hover) and (pointer: fine) {
  .day-box.revealed:hover::before { transform: scale(calc(1 / var(--recede))); }
}

.day-box.revealed .day-cover {
  /* Anchors the sheen and the lit edge below; the cover has no positioned
     children of its own, so this costs nothing else. */
  position: relative;
  transition: transform var(--hover-ease), box-shadow var(--hover-ease),
              border-radius var(--hover-ease), border-color var(--hover-ease);
}

/* Both overlays share a frame and a fade. They sit inside the cover's
   overflow:hidden, so they take its rounded corners for free. ::before paints
   under ::after, which is the order we want: the lit edge reads as the sleeve's
   rim and should sit on top of the sheen, not under it. */
.day-box.revealed .day-cover::before,
.day-box.revealed .day-cover::after {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit; pointer-events: none;
  opacity: 0; transition: opacity var(--hover-ease);
}

/* Specular sheen. Placed from the pointer, so it slides across the artwork as
   the sleeve turns instead of sitting on it like a decal.
   Blended rather than laid on at flat alpha, which is the trick the holographic
   card libraries use: straight white over the artwork lifts every pixel
   equally and erases the detail under the highlight. `overlay` reads the
   backdrop first — it doubles what is already dark and drives what is already
   light toward white — so the sleeve's own contrast survives the gloss.
   The alphas below were set by eye against real artwork, not derived: overlay
   is non-linear, so they do not read as their numbers would suggest. */
.day-box.revealed .day-cover::before {
  /* The hot spot does not sit under the cursor. It is displaced from the
     sleeve's centre by three times the cursor's own displacement — --px/--py are
     -1..1 across the card, so the cursor sits at 50% + px*50% and the
     highlight at 50% + px*150%. A reflection tracks faster than the eye that
     moves it, and pinning it to the pointer made the sleeve read as flat paper
     with a torch on it. Travelling at 3x, it swings off the edge at the
     extremes, which is why the radius is large enough to still wash the sleeve
     from outside it. */
  background:
    radial-gradient(90% 90% at
      calc(50% + var(--px) * 150%) calc(50% + var(--py) * 150%),
      rgba(255, 255, 255, 0.66), rgba(255, 255, 255, 0.144) 46%, rgba(255, 255, 255, 0) 72%);
  mix-blend-mode: overlay;
}

/* Lit inner edge. A 1px ring rather than a border: the gradient is painted
   across the whole box and then everything but the rim is masked away, which
   is the only way to get a border whose brightness varies around it.
   CONIC, not radial. A radial highlight can only slide across the box, so the
   bright patch stayed on whichever side its centre drifted toward and never
   truly went round. A conic gradient is a function of the angle about the
   centre, which is exactly the perimeter, so the hot spot orbits the rim.
   --rim-angle points at the corner that has come FORWARD, which is opposite
   the pointer, because the corner under the pointer is the one that recedes.
   Tip the top-left corner back and the light leaves it for the bottom-right,
   which is what an edge catching a light actually does.
   The 0.22 bias sets where the hot spot rests when the card is flat — without
   it atan2(0,0) is undefined and the highlight would spin as the pointer
   crossed the centre. It is small enough that any real tilt overrules it.
   --rim-a is the tilt magnitude, and it drives contrast rather than position:
   flat, the ring is near-uniform, so the unstable angle at the centre has
   nothing visible to spin. Tilted, the lit edge and the dark edge separate
   hard. That coupling is what stops the dead zone from ever showing. */
.day-box.revealed .day-cover::after {
  --rim-a: clamp(0, hypot(var(--px), var(--py)), 1);
  --rim-angle: atan2(calc(-1 * var(--px) - 0.22), calc(var(--py) + 0.22));
  padding: 1px;
  background: conic-gradient(from var(--rim-angle),
      rgba(255, 255, 255, calc(0.32 + 0.62 * var(--rim-a))) 0deg,
      rgba(255, 255, 255, calc(0.16 + 0.10 * var(--rim-a))) 72deg,
      rgba(255, 255, 255, calc(0.10 - 0.09 * var(--rim-a))) 180deg,
      rgba(255, 255, 255, calc(0.16 + 0.10 * var(--rim-a))) 288deg,
      rgba(255, 255, 255, calc(0.32 + 0.62 * var(--rim-a))) 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  /* Same treatment as the sheen. Composited normally the rim was flat white
     laid over the artwork, which went milky wherever the sleeve was already
     pale; blended, it brightens what is dark and drives what is light toward
     white, so it reads as light on an edge rather than paint. */
  mix-blend-mode: overlay;
}

/* Pointer-only: :hover latches after a tap on a touchscreen, so a returning
   reader would find one card stuck mid-animation. */
@media (hover: hover) and (pointer: fine) {
  .day-box.revealed:hover {
    /* While tracking, the pointer vars get the fast clock — same reasoning as
       the tilt: a highlight 240ms behind the cursor reads as lag. The card's
       own scale keeps the slow one. */
    transition: transform var(--hover-ease), --px 90ms linear, --py 90ms linear;
    transform: scale(var(--recede));
    /* The enlarged cover overhangs the shrunken card. It lands in the grid
       gap rather than on a neighbour, but the depth reading only holds if
       the lifted card is unambiguously in front. */
    z-index: 2;
  }
  /* The cover inherits the group's shrink, so its own scale has to cancel
     that out before any growth is left over. Written as the division rather
     than the product it evaluates to, so --advance stays the number the
     reader actually perceives and the two stay in step if either changes. */
  /* The body:not(.admin-page) prefix buys specificity, not scope — .day-box
     only ever renders on the public page. The .today and .selected rules blank
     this same border to transparent at (0,4,1), which out-ranked a bare
     .day-box.revealed:hover .day-cover at (0,4,0); on a selected card the
     border stayed transparent and, because background-clip is padding-box, the
     near-black card showed through it as a dark line between the artwork and
     the ring. Matching their prefix takes this to (0,5,1). */
  body:not(.admin-page) .day-box.revealed:hover .day-cover {
    transform: scale(var(--cover-scale));
    /* Nearly square as it lifts. The 6px rest radius reads as a UI tile; at 2px
       it reads as a printed sleeve with the corner knock a real one has. Both
       overlays take border-radius: inherit, so the sheen's clip and the lit rim
       follow the same curve. */
    border-radius: 2px;
    /* Three rings, painted front to back:
       1. a solid outer edge in the sampled colour — the same value the caption
          chips are printed in, so sleeve and labels read as one object. It is
          a spread shadow rather than a border because a border would eat into
          the cover's box and rescale the artwork inside it;
       2. a depth shadow;
       3. a glow in the same colour, so the card lights its surroundings with
          the record's own palette rather than a generic halo.
       Without (1) the sleeve had no defined edge and dissolved into the white
       card sitting behind it. */
    /* The cover already carries a 1px hairline of its own, and background-clip
       is padding-box, so the artwork stops inside it. Left pale, that hairline
       sat between the artwork and the ring and read as a gap. Recolouring it
       makes hairline and ring one continuous 2px band flush to the image.
       border-COLOR, never border-width: changing the width would shift the
       padding box that background-size: cover scales against, and the artwork
       would visibly resize on every hover. */
    border-color: rgb(var(--chip-rgb, 43 38 32));
    box-shadow:
      0 0 0 1px rgb(var(--chip-rgb, 43 38 32)),
      0 10px 22px -6px rgb(0 0 0 / 0.4),
      0 0 26px -4px rgb(var(--chip-rgb, 43 38 32) / 0.55);
  }
  .day-box.revealed:hover .day-cover::before,
  .day-box.revealed:hover .day-cover::after { opacity: 1; }
}

/* Captions: artist above the sleeve, title below, typed in on hover.
   .cover-slot keeps the cover's layout box while the cover itself scales, so
   the captions have a still thing to anchor to. It also supplies the
   perspective for the tilt — its box is the cover's square, so the vanishing
   point sits at the sleeve's centre without having to be positioned. */
.cover-slot { position: relative; width: 100%; perspective: 340px; }

/* Rotation lives on its own wrapper so it can keep its own clock. Sharing one
   transform with the scale would force one transition on both, and a cursor
   the sleeve chases 240ms behind reads as lag rather than weight. */
.cover-3d {
  width: 100%;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform var(--hover-ease);
}
@media (hover: hover) and (pointer: fine) {
  /* While the pointer is down on the card, track it almost immediately — just
     enough smoothing to take the jitter off raw mousemove. On leave :hover
     drops and the slower resting transition above eases it back to flat,
     together with the card settling. */
  .day-box.revealed:hover .cover-3d {
    transition: transform 90ms ease-out;
    /* Promoted only while the pointer is on this card. Declaring it at rest
       would keep a layer alive for every card in the archive at once, which
       costs more than it saves. */
    will-change: transform;
  }
}

/* The captions track the cover's *visual* edges, not its layout box: the
   cover grows past .cover-slot on hover, so both the left offset and the
   width are derived from --cover-scale. Left edge sits half the overhang out;
   width is the grown width. Percentages resolve against the slot, and the
   slot is square, so the same expression serves the vertical clearance below.
   Deliberately no counter-scale here — the caption shrinks with the group like
   everything else, which is exactly what keeps it the cover's width rather
   than 18% wider than it. */
/* .cap is the frame: it sets where the caption sits and how wide it may run
   before wrapping. It carries no ink of its own. */
.day-box.revealed .cap {
  position: absolute;
  left: calc((1 - var(--cover-scale)) / 2 * 100%);
  width: calc(var(--cover-scale) * 100%);
  text-align: left;
  /* Titles run to 32 characters in a box this narrow, so they wrap. Anchoring
     the artist by its bottom and the title by its top means later lines grow
     away from the sleeve and neither caption shifts off its edge. */
  overflow-wrap: anywhere;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.01em;
  /* Roomy enough that consecutive line backgrounds read as separate stripes
     instead of one welded block — the padding below has to fit in the leading. */
  line-height: 1.85;
}

/* The background belongs to the inline run, not the frame, so it stops at the
   end of each line rather than boxing the whole wrapped paragraph. That is
   what box-decoration-break: clone buys: every line fragment gets its own
   padding and its own rounded corners, so a short last line stays short. */
.day-box.revealed .cap .ink {
  display: inline;
  color: #fff; background: rgb(var(--chip-rgb, 43 38 32));
  padding: 0.14em 0.34em; border-radius: 3px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
/* Before the first character lands and after the last is cleared there is no
   text — without this the padding alone still paints a small coloured tab. */
.day-box.revealed .cap .ink:empty { display: none; }

.day-box.revealed .cap-artist { bottom: calc(100% + (var(--cover-scale) - 1) / 2 * 100% + 4px); }
.day-box.revealed .cap-title  { top:    calc(100% + (var(--cover-scale) - 1) / 2 * 100% + 4px); }

/* Block caret, gone the moment the last character lands. */
.day-box.revealed .cap .ink.typing::after {
  content: ''; display: inline-block; vertical-align: -0.1em;
  width: 0.5em; height: 0.9em; margin-left: 0.1em; background: #fff;
}

@media (hover: hover) and (pointer: fine) {
  /* The captions land where the day name and theme name sit, and say the same
     thing more precisely. Fading those out is what makes room. */
  .day-box.revealed:hover .day-name,
  .day-box.revealed:hover .theme-name { opacity: 0; }
}
.day-box.revealed .day-name,
.day-box.revealed .theme-name { transition: opacity var(--hover-ease); }

@media (prefers-reduced-motion: reduce) {
  .day-box.revealed,
  .day-box.revealed .day-cover,
  .day-box.revealed:hover,
  .day-box.revealed:hover .day-cover { transform: none; transition: none; }
  .day-box.revealed .cap .ink.typing::after { display: none; }
  /* The sheen and rim still appear, they just stop sliding — there is no
     pointer-driven placement without the tilt that feeds it. */
  .day-box.revealed .day-cover::before,
  .day-box.revealed .day-cover::after { transition: none; }
}

@media (max-width: 700px) {
  .week-row { grid-auto-flow: column; grid-auto-columns: 92px; overflow-x: auto; }
}

#selected-date-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  background: #ece4d6; border: 1px solid #cbc2b4; border-radius: 8px;
  padding: 0.6rem 0.9rem; margin-bottom: 0.6rem; font-family: system-ui, sans-serif;
}
#selected-date-banner[hidden] { display: none; }
#selected-date-text { font-size: 0.85rem; color: #4d453a; }
#selected-date-back { white-space: nowrap; }
body:not(.admin-page) #selected-date-banner {
  background: var(--sleeve); border-color: var(--hairline); border-left: 3px solid var(--accent);
  border-radius: 4px; font-family: 'IBM Plex Mono', ui-monospace, monospace;
}
body:not(.admin-page) #selected-date-text { color: var(--ink-faded); font-size: 0.78rem; letter-spacing: 0.02em; }
body:not(.admin-page) #selected-date-back { color: var(--accent); font-weight: 500; }
#main-content-below { margin-top: 1.4rem; }
body:not(.admin-page) #main-content-below { margin-top: 1.9rem; }
#main-content-below .placeholder-notice {
  display: inline-block; font-family: system-ui, sans-serif; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.05em; color: #a33430;
  border: 1px dashed #a33430; border-radius: 4px; padding: 0.15rem 0.5rem; margin-bottom: 0.8rem;
}
body:not(.admin-page) #main-content-below .placeholder-notice {
  font-family: 'IBM Plex Mono', ui-monospace, monospace; color: var(--accent); border-color: var(--accent);
}

button.link { background: none; border: none; color: #8a5a2b; padding: 0.25rem 0; font-size: 0.9rem; cursor: pointer; }
body:not(.admin-page) button.link { color: var(--accent); font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.85rem; }

#article header.article-head { display: block; margin: 1rem 0 1.5rem; }
/* The cover and its listen buttons float together, so the buttons sit under
   the artwork rather than under the prose. */
#article .cover-block { float: right; width: 200px; margin: 0 0 1rem 1.2rem; }
#article img.cover { width: 200px; height: 200px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); display: block; }
/* Hairline rule with the label sitting in the gap. */
/* Equal margins top and bottom so the rule sits centred in the gap between
   the artwork and the buttons — it was 14px above and 8px below. */
#article .stream-rule {
  display: flex; align-items: center; gap: 0.55rem;
  margin: 0.7rem 0;
}
#article .stream-rule::before,
#article .stream-rule::after {
  content: ''; flex: 1; height: 1px; background: #ddd4c4;
}
#article .stream-rule span {
  font-family: system-ui, sans-serif; font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: #9a8d7a;
}
#article .listen-links { display: flex; gap: 0.4rem; }
#article .listen-btn {
  flex: 1; display: flex; align-items: center; justify-content: center;
  height: 2.2rem; border: none; border-radius: 5px; text-decoration: none;
  transition: opacity 0.15s;
}
#article .listen-btn svg { height: 1.05rem; width: auto; display: block; }
#article .listen-btn.apple { background: #000; color: #fff; }
#article .listen-btn.spotify { background: #1db954; color: #fff; }
/* The Apple glyph reads smaller than the Spotify disc at the same height. */
#article .listen-btn.apple svg { height: 1.15rem; margin-top: -1px; }
#article .listen-btn:hover { opacity: 0.82; }
#article .listen-btn:focus-visible { outline: 2px solid var(--accent, #8a5a2b); outline-offset: 2px; }
@media (max-width: 620px) {
  #article .cover-block { float: none; width: auto; max-width: 200px; margin: 0 0 1rem; }
}
@media (prefers-reduced-motion: reduce) { #article .listen-btn { transition: none; } }
/* Unclickable on paper, and a solid black block wastes ink. */
@media print { #article .listen-links, #article .stream-rule { display: none; } }
#article h2.headline { font-size: 1.9rem; line-height: 1.2; margin: 0.4rem 0; }
#article .dek { font-size: 1.1rem; color: #4d453a; font-style: italic; margin: 0.4rem 0 0.8rem; }
#article .byline { font-family: system-ui, sans-serif; font-size: 0.78rem; color: #9a8d7a; }
#article h3 { font-size: 1.2rem; margin: 1.6rem 0 0.4rem; }
#article .tags { font-family: system-ui, sans-serif; font-size: 0.78rem; color: #8a5a2b; margin-top: 1.4rem; }
#article .sources { font-family: system-ui, sans-serif; font-size: 0.78rem; color: #9a8d7a; margin-top: 0.8rem; }
#article .sources a { color: #8a5a2b; }
.artist-blurb { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid #e8e1d5; }
.artist-blurb h3 { font-size: 1rem; margin: 0 0 0.4rem; }
#artist-view #artist .sources { font-family: system-ui, sans-serif; font-size: 0.78rem; color: #9a8d7a; margin-top: 1rem; }
#artist-view #artist .sources a { color: #8a5a2b; }
body:not(.admin-page) #article img.cover {
  border-radius: 4px; border: 1px solid var(--hairline);
  box-shadow: 0 3px 18px rgba(28,23,18,0.14);
}
body:not(.admin-page) #article h2.headline {
  font-family: 'Fraunces', Georgia, serif; font-weight: 600; font-size: 2.15rem;
  line-height: 1.12; letter-spacing: -0.01em;
}
body:not(.admin-page) #article .dek {
  font-family: 'Fraunces', Georgia, serif; font-weight: 400; font-style: italic;
  font-size: 1.18rem; color: var(--ink-faded);
}
body:not(.admin-page) #article .byline {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  display: flex; flex-direction: column; gap: 0.2rem;
  text-transform: uppercase;
  margin-bottom: 0.9rem; padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--hairline);
}
body:not(.admin-page) #article .byline .byline-theme {
  font-size: 0.8rem; letter-spacing: 0.08em; font-weight: 600; color: var(--accent);
}
/* Present to assistive tech and search, absent from the page. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
#article .lang-switch { display: flex; gap: 0.5rem; margin-top: 0.15rem; }
#article .lang-opt {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 0.72rem; letter-spacing: 0.06em;
  color: #9a8d7a; text-transform: uppercase;
  border-bottom: 1px solid transparent;
}
#article .lang-opt:hover { color: #4d453a; }
#article .lang-opt.active { color: var(--accent, #8a5a2b); border-bottom-color: currentColor; cursor: default; }
#article .lang-opt:focus-visible { outline: 2px solid var(--accent, #8a5a2b); outline-offset: 2px; }
body:not(.admin-page) #article .byline .byline-work {
  font-size: 1rem; letter-spacing: 0.02em; font-weight: 500; color: var(--ink);
}
body:not(.admin-page) #article h3 {
  font-family: 'Fraunces', Georgia, serif; font-weight: 600; font-size: 1.28rem;
  border-top: 1px solid var(--hairline); padding-top: 1.1rem; margin: 1.9rem 0 0.5rem;
  /* A plain block's border-top spans the full column and slides underneath the
     floated cover, so the first section rule ran ~220px longer than the byline
     rule above it and collided with the artwork. flow-root makes the heading an
     independent formatting context, which narrows its box to stop at the float
     — the same reason .byline (display:flex) already stops cleanly. Headings
     below the artwork are unaffected and stay full width. */
  display: flow-root;
}
/* Section headings are hidden (see .visually-hidden), so the h3 is now purely
   the rule between sections. Three things this needs to get right:
   - it must come AFTER the block above, not before: same specificity, and
     that one sets the padding-top this has to clear;
   - direct child only. #artist-blurb lives inside #article, so a descendant
     selector collapses "About the artist" too — its heading is still shown;
   - line-height: 0 kills the line box the absolutely-positioned span leaves. */
body:not(.admin-page) #article > h3 {
  padding-top: 0; line-height: 0; margin: 2.1rem 0 1.3rem;
}
body:not(.admin-page) #article .tags { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.7rem; color: var(--accent); }
body:not(.admin-page) #article .sources { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.7rem; color: var(--ink-faded); }
body:not(.admin-page) #article .sources a { color: var(--accent); }
body:not(.admin-page) .artist-blurb { border-top-color: var(--hairline); }
body:not(.admin-page) .artist-blurb h3 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; }
body:not(.admin-page) #artist-view #artist .sources { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.7rem; color: var(--ink-faded); }
body:not(.admin-page) #artist-view #artist .sources a { color: var(--accent); }

footer#admin {
  margin-top: 3rem; padding: 0.9rem 1rem; border: 1px dashed #cbc2b4; border-radius: 8px;
  font-family: system-ui, sans-serif; font-size: 0.8rem; color: #6b5f4e;
}
footer#admin a { color: #8a5a2b; }
body:not(.admin-page) footer#admin {
  border: none; border-top: 1px solid var(--hairline); border-radius: 0;
  margin-top: 3.5rem; padding: 1rem 0 0.2rem;
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.72rem; color: var(--ink-faded);
}
body:not(.admin-page) footer#admin a { color: var(--accent); }
footer#admin .auth-box, footer#admin .auth-form, footer#admin .auth-error {
  font-family: inherit; font-size: inherit; color: inherit;
}
footer#admin .auth-form input { font-family: inherit; border-color: var(--hairline); }
footer#admin .auth-form button, footer#admin .auth-box .linkish { font-family: inherit; border-color: var(--ink-faded); color: var(--ink); }
footer#admin .auth-box .linkish { color: var(--accent); border: none; }
.admin-buttons { display: flex; gap: 0.5rem; margin-top: 0.6rem; flex-wrap: wrap; align-items: center; }
.admin-buttons button {
  font-size: 0.78rem; padding: 0.4rem 0.7rem; border: 1px solid #6b5f4e;
  border-radius: 6px; background: #fff; color: #201c17; cursor: pointer;
  font-family: system-ui, sans-serif;
}
.admin-buttons button:disabled { opacity: 0.5; cursor: default; }
.admin-buttons .apple-music-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; padding: 0; border: 1px solid #6b5f4e; border-radius: 50%;
  background: #fff; color: #201c17; cursor: pointer; text-decoration: none;
  font-size: 0.75rem; line-height: 1;
}
.admin-buttons input {
  font-size: 0.78rem; padding: 0.4rem 0.6rem; width: 160px;
  border: 1px solid #cbc2b4; border-radius: 6px; font-family: system-ui, sans-serif;
}
.pill-link {
  font-size: 0.78rem; padding: 0.4rem 0.7rem; border: 1px solid #6b5f4e;
  border-radius: 6px; background: #fff; color: #201c17; cursor: pointer;
  font-family: system-ui, sans-serif; text-decoration: none; display: inline-block;
}

/* admin page */
.admin-badge {
  font-family: system-ui, sans-serif; font-size: 0.7rem; vertical-align: middle;
  background: #8a5a2b; color: #fbf8f3; border-radius: 999px; padding: 0.15rem 0.55rem;
}
.admin-section {
  margin: 1.4rem 0; padding: 1rem 1.2rem; border: 1px dashed #cbc2b4; border-radius: 8px;
  font-family: system-ui, sans-serif; font-size: 0.85rem; color: #4d453a;
}
.admin-section h2 { font-family: Georgia, serif; font-size: 1.1rem; margin: 0 0 0.4rem; color: #201c17; }
.admin-section .hint { margin: 0 0 0.6rem; font-size: 0.78rem; color: #9a8d7a; }
.admin-section pre.result {
  background: #fff; border: 1px solid #e8e1d5; border-radius: 6px; padding: 0.7rem;
  font-size: 0.74rem; white-space: pre-wrap; margin-top: 0.7rem;
}
#mine-status { font-size: 0.78rem; color: #8a5a2b; }
.pool-card { cursor: default; position: relative; }
.pool-card .pool-body { flex: 1; }
.pool-card h2 { font-size: 1.05rem; }
.pool-card .meta a { color: #8a5a2b; }

/* artist name / article title, made clickable inline within a card heading */
h2 button.artist-btn {
  background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit;
  cursor: pointer;
}
h2 button.artist-btn:hover { text-decoration: underline; color: #8a5a2b; }
h2 a.article-link { color: inherit; text-decoration: none; }
h2 a.article-link:hover { text-decoration: underline; color: #8a5a2b; }

/* articles + hooks */
.article-row { position: relative; cursor: default; align-items: center; }
.article-row .pool-body { flex: 1; }
.article-row h2 { font-size: 1rem; }
.hooks-btn { position: relative; }
.hook-badge {
  display: inline-block; min-width: 1.1rem; padding: 0 0.3rem; margin-left: 0.35rem;
  border-radius: 999px; background: #8a5a2b; color: #fff; font-size: 0.68rem; line-height: 1.35;
  text-align: center;
}
.hooks-popover {
  position: absolute; top: 100%; right: 0; z-index: 10; margin-top: 0.3rem;
  width: 320px; max-height: 320px; overflow-y: auto;
  background: #fff; border: 1px solid #cbc2b4; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.15); padding: 0.6rem;
}
.hook-item {
  display: flex; gap: 0.5rem; align-items: flex-start; padding: 0.4rem 0.2rem;
  font-size: 0.82rem; color: #201c17; border-bottom: 1px solid #f0ebe1; cursor: pointer;
}
.hook-item:last-child { border-bottom: none; }
.hook-item input { margin-top: 0.2rem; flex-shrink: 0; }
.artist-popover {
  position: absolute; top: 100%; right: 0; z-index: 10; margin-top: 0.3rem;
  width: 300px; max-height: 320px; overflow-y: auto;
  background: #fff; border: 1px solid #cbc2b4; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.15); padding: 0.6rem;
  font-size: 0.82rem; color: #201c17;
}
.artist-popover h3 { margin: 0 0 0.4rem; font-size: 0.95rem; }
.artist-popover details { margin-top: 0.4rem; }
.artist-popover summary { cursor: pointer; color: #8a5a2b; }
/* auth widget */
.auth-box { font-family: system-ui, sans-serif; font-size: 0.8rem; color: #6b5f4e; display: inline-flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.auth-form input { padding: 0.32rem 0.5rem; border: 1px solid #cbc2b4; border-radius: 5px; font-size: 0.78rem; font-family: system-ui, sans-serif; }
.auth-form button, .auth-box .linkish { padding: 0.32rem 0.6rem; font-size: 0.78rem; border-radius: 5px; border: 1px solid #6b5f4e; background: #fff; color: #201c17; cursor: pointer; }
.auth-box .linkish { border: none; color: #8a5a2b; padding: 0; background: none; }
.auth-error { color: #a33430; }

.source-badge {
  display: inline-block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em;
  background: #ece4d6; color: #6b5f4e; border-radius: 4px; padding: 0.05rem 0.4rem;
}
.admin-buttons select, .admin-buttons label {
  font-size: 0.78rem; font-family: system-ui, sans-serif;
}
.admin-buttons select { padding: 0.35rem 0.5rem; border: 1px solid #cbc2b4; border-radius: 6px; background: #fff; }

/* --- tabbed dashboard (Pool / Articles / Artists / Blog) --- */
body.admin-page { max-width: 1600px; }
#admin-body { margin: 0 auto; }
#tabs { display: flex; gap: 0.4rem; margin: 0 0 1rem; border-bottom: 1px solid #cbc2b4; font-family: system-ui, sans-serif; }
.tab-btn {
  font-size: 0.9rem; padding: 0.6rem 1rem; border: none; border-bottom: 2px solid transparent;
  background: none; color: #6b5f4e; cursor: pointer;
}
.tab-btn.active { color: #201c17; border-bottom-color: #8a5a2b; font-weight: 600; }

/* Pushed to the right edge of the tab strip — it belongs to the whole
   dashboard, not to any one tab. */
#quality-picker {
  margin-left: auto; align-self: center; display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.78rem; color: #6b5f4e; padding-bottom: 0.4rem;
}
#quality-picker select {
  font-family: inherit; font-size: 0.78rem; padding: 0.2rem 0.4rem;
  border: 1px solid #cbc2b4; border-radius: 3px; background: #fffdf8; color: #201c17;
}
#quality-note { margin: -0.7rem 0 1rem; text-align: right; font-size: 0.72rem; color: #9a8d7a; font-family: system-ui, sans-serif; }

/* Articles tab — version picker above the editor */
.version-bar {
  display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  margin: 0 0 0.3rem; font-size: 0.8rem; color: #6b5f4e; font-family: system-ui, sans-serif;
}
.version-bar select {
  font-family: inherit; font-size: 0.8rem; padding: 0.25rem 0.4rem;
  border: 1px solid #cbc2b4; border-radius: 3px; background: #fffdf8; color: #201c17;
}
#ed-version-note { margin: 0 0 1rem; font-size: 0.74rem; color: #9a8d7a; font-family: system-ui, sans-serif; }
/* An archived version on screen: visibly not yours to type into. */
.readonly { background: #f4efe4; color: #4a4136; cursor: default; }
.confirm-q { font-size: 0.78rem; color: #7a3b25; font-family: system-ui, sans-serif; }
button.danger { background: #7a3b25; color: #fdf9f2; border-color: #7a3b25; }

.dashboard { display: flex; gap: 1.2rem; align-items: flex-start; }
.dash-list {
  flex: 0 0 300px; max-height: 75vh; overflow-y: auto;
  border: 1px solid #e8e1d5; border-radius: 8px; background: #fff;
}
.dash-list .admin-buttons, .dash-list .search-box { padding: 0.7rem 0.8rem; border-bottom: 1px solid #e8e1d5; margin: 0; }
.dash-list.cal-wide { flex-basis: 640px; max-height: none; overflow: visible; }
.dash-detail {
  flex: 1; min-width: 0; border: 1px solid #e8e1d5; border-radius: 8px; background: #fff;
  padding: 1.2rem; min-height: 320px; font-family: system-ui, sans-serif; font-size: 0.85rem; color: #4d453a;
}
.dash-detail h2 { font-family: Georgia, serif; font-size: 1.2rem; color: #201c17; margin: 0 0 0.6rem; }

.list-item {
  display: flex; gap: 0.6rem; align-items: center; padding: 0.6rem 0.8rem;
  border-bottom: 1px solid #f0ebe1; cursor: pointer; font-family: system-ui, sans-serif; font-size: 0.83rem;
}
.list-item:last-child { border-bottom: none; }
.list-item:hover { background: #fbf8f3; }
.list-item.selected { background: #f0ebe1; }
.list-item img { width: 34px; height: 34px; border-radius: 4px; object-fit: cover; flex-shrink: 0; }
.list-item .item-main { flex: 1; min-width: 0; }
.list-item .item-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #201c17; }
.list-item .item-sub { font-size: 0.72rem; color: #9a8d7a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.list-item.disabled { opacity: 0.45; cursor: default; }
.list-item .badge {
  font-size: 0.64rem; padding: 0.1rem 0.4rem; border-radius: 999px; background: #ece4d6; color: #6b5f4e; flex-shrink: 0;
}
.list-item .mining-badge { background: #8a5a2b; color: #fbf8f3; }
@media (prefers-reduced-motion: no-preference) {
  .list-item .mining-badge { animation: mining-pulse 1.6s ease-in-out infinite; }
}
@keyframes mining-pulse { 50% { opacity: 0.45; } }

/* editors (Articles / Artists / theme-pool mine controls) */
.editor-field { margin-bottom: 0.9rem; }
.editor-field label {
  display: block; font-size: 0.7rem; color: #9a8d7a; margin-bottom: 0.25rem;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.editor-field input[type=text], .editor-field textarea {
  width: 100%; padding: 0.5rem 0.6rem; border: 1px solid #cbc2b4; border-radius: 6px;
  font-family: Georgia, serif; font-size: 0.95rem; color: #201c17;
}
.editor-field textarea { resize: vertical; min-height: 3.2rem; }
.section-editor { border: 1px solid #e8e1d5; border-radius: 6px; padding: 0.8rem; margin-bottom: 0.8rem; }
.section-editor .editor-field:last-child { margin-bottom: 0; }
.search-box { display: flex; gap: 0.5rem; }
.search-box input { flex: 1; }

/* artist bio editor: pick a version via tabs, edit it in one shared textarea */
.version-tabs { display: flex; gap: 0.3rem; margin-bottom: 0; font-family: system-ui, sans-serif; }
.version-tab-btn {
  font-size: 0.8rem; padding: 0.45rem 1rem; border: 1px solid #cbc2b4; border-bottom: none;
  border-radius: 6px 6px 0 0; background: #f0ebe1; color: #6b5f4e; cursor: pointer;
}
.version-tab-btn.active { background: #fff; color: #201c17; font-weight: 600; }
.full-text-editor {
  display: block; width: 100%; min-height: 55vh; padding: 1rem 1.1rem;
  border: 1px solid #cbc2b4; border-radius: 0 6px 6px 6px; margin-bottom: 0.9rem;
  font-family: Georgia, serif; font-size: 1rem; line-height: 1.7; color: #201c17; resize: vertical;
}

@media (max-width: 720px) {
  .dashboard { flex-direction: column; }
  .dash-list { flex: none; width: 100%; max-height: 240px; }
  .dash-list.cal-wide { max-height: none; }
}

/* Blog tab calendar (FullCalendar) — tuned to the app's warm palette */
#fc-calendar {
  padding: 0.8rem;
  --fc-border-color: #e8e1d5;
  --fc-page-bg-color: #fff;
  --fc-neutral-bg-color: #f0ebe1;
  --fc-today-bg-color: #fdf3e4;
  --fc-button-bg-color: #fff;
  --fc-button-border-color: #6b5f4e;
  --fc-button-text-color: #201c17;
  --fc-button-hover-bg-color: #f0ebe1;
  --fc-button-hover-border-color: #6b5f4e;
  --fc-button-active-bg-color: #ece4d6;
  --fc-button-active-border-color: #6b5f4e;
  font-family: system-ui, sans-serif;
  font-size: 0.82rem;
}
#fc-calendar .fc-toolbar-title { font-family: Georgia, serif; font-size: 1.1rem; color: #201c17; }
#fc-calendar .fc-button { text-transform: none; box-shadow: none !important; }
#fc-calendar .fc-daygrid-day-frame { cursor: pointer; }
#fc-calendar .fc-daynum { color: #4d453a; }
#fc-calendar .fc-daytheme { margin-left: 0.3rem; font-size: 0.85rem; }
#fc-calendar .fc-day-selected { background: #f0ebe1 !important; }
#fc-calendar .fc-day-today { }
#fc-calendar .fc-event {
  border: none; font-size: 0.68rem; padding: 0 0.25rem; margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#fc-calendar .fc-status-unassigned { background: #e8e1d5; color: #9a8d7a; }
#fc-calendar .fc-status-progress { background: #ece4d6; color: #6b5f4e; }
#fc-calendar .fc-status-ready { background: #cfe3cf; color: #2f4f2f; }
#fc-calendar .fc-status-error { background: #f0c9c9; color: #7a2b2b; }
