/* ==========================================================================
   Time Pass — confessions.css
   The confession wall: a pinboard of sticky notes sitting above the arcade
   on the homepage. Paired with js/confessions.js.

   Design notes worth knowing before editing:

   * The notes are the only genuinely bright surface on a very dark site.
     That's on purpose — the board is the front door now, and paper against
     a dark wall is what makes it read as a board rather than another panel.
     Note text is dark ink on the paper, NOT the site's chalk-on-dark, so
     every note carries its own contrast (all five colours clear AA against
     #23201A ink).

   * "3D" here is real perspective, not a drop shadow pretending. Each note
     sits in a perspective container and is tilted by JS from the pointer
     position (js/confessions.js -> wireNoteTilt), the same technique the
     game tiles and hero radar already use, so the whole homepage moves
     with one visual grammar instead of two.

   * Every note keeps a fixed random tilt from the database (tilt_deg), so
     a note stays where it was pinned across reloads. The hover tilt is
     layered ON TOP of that base rotation — see --note-tilt.
   ========================================================================== */

/* ---- The board itself ---------------------------------------------------- */

.cb-board-wrap {
  position: relative;
  border-radius: 1.25rem;
  padding: clamp(1rem, 3vw, 2rem);
  /* A wall, not a panel: warmer and lighter than bg-panel so the paper has
     something to sit against, but still firmly inside the dark theme. */
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 60%),
    linear-gradient(160deg, #1d202b 0%, #171922 100%);
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 30px 60px -30px rgba(0, 0, 0, 0.8);
  overflow: hidden;
}

/* Faint cork/paper tooth. Pure CSS — no image request for a texture that
   is barely meant to be noticed. */
.cb-board-wrap::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    radial-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px);
  background-size: 22px 22px, 34px 34px;
  background-position: 0 0, 11px 17px;
}

/* The pile.
   ---------------------------------------------------------------------------
   Not a grid any more. The notes are absolutely positioned and thrown across
   a fixed-height area — roughly the height two notes used to take — so they
   land on top of one another the way paper does when it's pinned to the same
   board by twenty different people.

   Positions come from each note's id (js/confessions.js -> scatter), never
   from Math.random(): a pile that rearranges itself on every reload stops
   reading as a physical object. The same note lands in the same spot forever.

   Because they overlap heavily, a resting note shows its title and little
   else. Hovering (or tapping on a phone) lifts it clear and scales it up so
   it's readable in place; a second tap opens it in full. That's the whole
   interaction: glance, lift, open.
   ------------------------------------------------------------------------ */
#confessionBoard { position: relative; }

.cb-pile {
  position: relative;
  /* Two notes tall, and that's the whole wall no matter how many are on it. */
  height: 340px;
  margin-top: 1rem;
  perspective: 1100px;
  perspective-origin: 50% 40%;
}

@media (min-width: 640px)  { .cb-pile { height: 400px; } }
@media (min-width: 1024px) { .cb-pile { height: 460px; } }

/* ---- A note -------------------------------------------------------------- */

.cb-note {
  --note-bg: #FFE27A;
  --note-bg-2: #FFD24A;
  --note-ink: #23201A;
  --note-tilt: 0deg;
  --lift: 1;

  position: absolute;
  /* Size is set per-note from the pile's width in JS, so a note is the same
     physical thing on a phone and a desktop rather than a percentage that
     collapses at one end. */
  width: 150px;
  height: 150px;
  display: flex;
  flex-direction: column;
  padding: 0.85rem 0.7rem 0.55rem;
  cursor: pointer;
  text-align: left;
  color: var(--note-ink);
  background: linear-gradient(160deg, var(--note-bg) 0%, var(--note-bg-2) 100%);
  border: 0;
  border-radius: 2px 2px 3px 3px;
  transform: rotate(var(--note-tilt));
  transform-origin: 50% 50%;
  z-index: var(--lift);
  transition: transform 0.32s cubic-bezier(0.22, 0.9, 0.32, 1),
              box-shadow 0.32s ease,
              filter 0.32s ease;
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.3),
    6px 10px 18px -6px rgba(0, 0, 0, 0.62);
}

/* Lift. Straightens up, grows, and jumps to the front — which is what makes
   a note buried under three others readable without opening it. */
.cb-note:hover,
.cb-note:focus-visible,
.cb-note.is-lifted {
  transform: rotate(0deg) scale(1.42);
  z-index: 90;
  filter: brightness(1.06);
  box-shadow:
    0 3px 5px rgba(0, 0, 0, 0.34),
    18px 30px 50px -12px rgba(0, 0, 0, 0.78);
}

.cb-note:focus-visible { outline: 2px solid #CCFF33; outline-offset: 3px; }

/* A lifted note shows more of itself — there is room for it now. */
.cb-note:hover .cb-note-excerpt,
.cb-note:focus-visible .cb-note-excerpt,
.cb-note.is-lifted .cb-note-excerpt {
  -webkit-line-clamp: 5;
  line-clamp: 5;
}

/* ---- The pin ------------------------------------------------------------- */

.cb-pin {
  position: absolute;
  /* Smaller than it was. At 18px the pin competed with the note's own title;
     at 12px it reads as hardware holding paper up, which is the job. */
  top: -6px;
  left: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  /* Off-centre highlight + a hard rim is what reads as a metal dome. */
  background:
    radial-gradient(circle at 32% 28%, #ffffff 0%, var(--pin-color, #FF4D2E) 42%, rgba(0, 0, 0, 0.55) 100%);
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.5),
    0 0 8px 1px var(--pin-glow, rgba(255, 77, 46, 0.45));
  /* Pushed toward the viewer so it sits above the paper when the note
     tilts, instead of rotating flat into it. */
  transform: translateZ(10px);
}

/* ---- Note contents ------------------------------------------------------- */

.cb-note-kind {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  align-self: flex-start;
  margin-bottom: 0.5rem;
  padding: 0.1rem 0.42rem;
  border-radius: 3px;
  background: rgba(35, 32, 26, 0.14);
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.75;
}

.cb-note-title {
  font-family: 'Rajdhani', ui-sans-serif, sans-serif;
  /* Scales with the note, which scales with the column — so the title stays
     proportionate whether there are two columns or four. */
  /* Smaller floor than before (0.9rem -> 0.78rem). At 0.9 a two-line title
     on a 130px phone note overflowed its own box and got cut mid-word; the
     clamp still grows it back on a wider screen where there's room. */
  font-size: clamp(0.78rem, 2.4vw, 1.02rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.01em;
  /* Titles are user text and can be one long word; without this a single
     unbroken string pushes the note wider than its grid cell. */
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cb-note-excerpt {
  margin-top: 0.35rem;
  font-size: clamp(0.63rem, 1.8vw, 0.74rem);
  line-height: 1.45;
  opacity: 0.82;
  overflow-wrap: anywhere;
  /* Three lines inside a square. The excerpt is a hook, not the confession —
     the database only sends 140 characters to a signed-out visitor anyway,
     and the whole thing opens on tap. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (min-width: 640px) {
  .cb-note-excerpt { -webkit-line-clamp: 4; line-clamp: 4; }
}

.cb-note-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  margin-top: auto;
  padding-top: 0.5rem;
  font-size: 0.56rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  opacity: 0.62;
}

/* The wall is deliberately not endless. It shows a boardful, fades at the
   bottom edge, and hands the rest to the "read everything" page below —
   which is what keeps it feeling like a physical board with a limit rather
   than a feed you scroll forever. */
.cb-board-wrap.is-capped { padding-bottom: 0; }

.cb-board-wrap.is-capped::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 130px;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(23, 25, 34, 0) 0%, rgba(23, 25, 34, 0.86) 62%, #171922 100%);
}

.cb-readall {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: 9999px;
  border: 1px solid rgba(204, 255, 51, 0.45);
  background: rgba(204, 255, 51, 0.1);
  color: #E8FFA6;
  font-family: 'Rajdhani', ui-sans-serif, sans-serif;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.7rem 1.6rem;
  cursor: pointer;
  text-decoration: none;
  transition: all 0.25s ease;
}

.cb-readall:hover {
  background: rgba(204, 255, 51, 0.2);
  border-color: rgba(204, 255, 51, 0.8);
}

.cb-readall-count {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 500;
  opacity: 0.7;
  text-transform: none;
  letter-spacing: 0;
}

.cb-note-stats { display: inline-flex; align-items: center; gap: 0.6rem; }
.cb-note-stat { display: inline-flex; align-items: center; gap: 0.22rem; }
.cb-note-stat svg { width: 11px; height: 11px; }

.cb-note-by {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.58rem;
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 55%;
}

/* ---- Voice notes --------------------------------------------------------- */

.cb-note-voice {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.4rem 0.45rem;
  border-radius: 4px;
  background: rgba(35, 32, 26, 0.1);
}

.cb-wave {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 18px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.cb-wave span {
  flex: 1;
  min-width: 2px;
  border-radius: 1px;
  background: currentColor;
  opacity: 0.45;
}

.cb-voice-len {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.6rem;
  opacity: 0.7;
}

/* ---- Note colours -------------------------------------------------------- */
/* Five papers, matched to the site palette but pushed light enough to hold
   dark ink. color_key in the database is 0-4 and maps straight onto these. */

.cb-c0 { --note-bg: #FFE9A3; --note-bg-2: #FFD75C; --pin-color: #FF4D2E; --pin-glow: rgba(255,77,46,0.55); }
.cb-c1 { --note-bg: #D8FFA8; --note-bg-2: #BDF56A; --pin-color: #2EC5FF; --pin-glow: rgba(46,197,255,0.55); }
.cb-c2 { --note-bg: #B9EEFF; --note-bg-2: #7FDCFF; --pin-color: #CCFF33; --pin-glow: rgba(204,255,51,0.55); }
.cb-c3 { --note-bg: #FFC9B8; --note-bg-2: #FFA88E; --pin-color: #CCFF33; --pin-glow: rgba(204,255,51,0.5); }
.cb-c4 { --note-bg: #EAD9FF; --note-bg-2: #D3B6FF; --pin-color: #FF7A54; --pin-glow: rgba(255,122,84,0.55); }

/* ---- "Post a confession" note ------------------------------------------- */
/* Sits in the grid as the first note so adding one is a physical act on the
   board, not a button parked somewhere else on the page. */

/* The one note that isn't square. It spans the full board width and keeps
   the taller shape from the original design — it's the call to action, and
   shrinking it into the grid alongside everything else would bury it. */
.cb-note-new {
  --note-ink: #F5F6F0;
  position: relative;
  display: flex;
  width: 100%;
  min-height: 168px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.55rem;
  padding: 1.4rem 1rem;
  color: var(--note-ink);
  background: rgba(255, 255, 255, 0.035);
  border: 1px dashed rgba(204, 255, 51, 0.4);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.25s ease;
  z-index: 2;
}

/* On a wide screen the Confess box is a square pinned into the top-left
   corner of the board, not a banner across the top of it.
   
   Two reasons. It stops the board opening with a full-width empty rectangle
   before you see a single confession — the wall should be the first thing you
   read. And it puts "add yours" physically among the notes, which is where
   the thought occurs, rather than in a header bar above them.
   
   Below 768px it stays a full-width block: on a phone there is no corner to
   spare, and a 190px square next to two 130px notes just looks like a third
   note you can't read. */
@media (min-width: 768px) {
  .cb-note-new {
    position: absolute;
    top: 0;
    left: 0;
    width: 190px;
    height: 190px;
    min-height: 0;
    margin: 0;
    padding: 1.1rem 0.9rem;
    /* Above every note, including a lifted one — it must stay clickable no
       matter what lands on top of it. */
    z-index: 96;
  }

  .cb-note-new-sub { font-size: 0.64rem; line-height: 1.4; }

  /* The pile now starts at the top of the board and runs the full height;
     scatter() in js/confessions.js keeps notes out from under the square. */
  .cb-pile { margin-top: 0; }
}

.cb-note-new:hover {
  border-color: rgba(204, 255, 51, 0.85);
  background: rgba(204, 255, 51, 0.07);
  box-shadow: 0 0 30px -8px rgba(204, 255, 51, 0.4);
}


.cb-note-new-plus {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(204, 255, 51, 0.45);
  color: #CCFF33;
  transform: translateZ(20px);
}

.cb-note-new-label {
  font-family: 'Rajdhani', ui-sans-serif, sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.cb-note-new-sub {
  font-size: 0.66rem;
  opacity: 0.5;
  max-width: 15rem;
}

/* ---- Board header + filters --------------------------------------------- */

.cb-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.cb-sorts { display: inline-flex; gap: 0.4rem; flex-wrap: wrap; }

.cb-sort {
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.04);
  color: rgba(245, 246, 240, 0.55);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.34rem 0.85rem;
  cursor: pointer;
  transition: all 0.25s ease;
}

.cb-sort:hover { color: rgba(245, 246, 240, 0.9); border-color: rgba(255, 255, 255, 0.25); }

.cb-sort[aria-pressed='true'] {
  background: rgba(204, 255, 51, 0.14);
  border-color: rgba(204, 255, 51, 0.5);
  color: #E8FFA6;
}

.cb-empty {
  grid-column: 1 / -1;
  padding: 3rem 1rem;
  text-align: center;
  font-size: 0.85rem;
  color: rgba(245, 246, 240, 0.4);
}

.cb-more-wrap { display: flex; justify-content: center; margin-top: 1.6rem; }

/* ---- Reading modal ------------------------------------------------------- */

.cb-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(0.75rem, 4vh, 3rem) 1rem;
  overflow-y: auto;
  background: rgba(8, 9, 12, 0.82);
  backdrop-filter: blur(8px);
  animation: cbFade 0.25s ease both;
}

@keyframes cbFade { from { opacity: 0; } to { opacity: 1; } }

.cb-modal {
  position: relative;
  width: 100%;
  max-width: 40rem;
  margin: auto;
  border-radius: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: #1A1C26;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.9);
  animation: cbRise 0.35s cubic-bezier(0.22, 0.9, 0.32, 1) both;
}

@keyframes cbRise {
  from { opacity: 0; transform: translateY(22px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* A strip of the note's own paper colour across the top, so opening a note
   feels connected to the one you clicked rather than a generic dialog. */
.cb-modal-paper {
  height: 6px;
  border-radius: 1rem 1rem 0 0;
  background: linear-gradient(90deg, var(--note-bg, #FFE27A), var(--note-bg-2, #FFD24A));
}

.cb-modal-body { padding: clamp(1.2rem, 3vw, 2rem); }

.cb-modal-title {
  font-family: 'Rajdhani', ui-sans-serif, sans-serif;
  font-size: clamp(1.4rem, 4vw, 1.9rem);
  font-weight: 700;
  line-height: 1.1;
  color: #F5F6F0;
  overflow-wrap: anywhere;
}

.cb-modal-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.6rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(245, 246, 240, 0.4);
}

.cb-modal-text {
  margin-top: 1.25rem;
  font-size: 0.94rem;
  line-height: 1.75;
  color: rgba(245, 246, 240, 0.85);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.cb-close {
  position: absolute;
  top: 0.85rem;
  right: 0.85rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.35);
  color: rgba(245, 246, 240, 0.6);
  cursor: pointer;
  transition: all 0.25s ease;
}

.cb-close:hover { color: #F5F6F0; border-color: rgba(255, 255, 255, 0.35); }

/* ---- The sign-in gate shown instead of the full text -------------------- */

.cb-gate {
  margin-top: 1.25rem;
  padding: 1.4rem;
  border-radius: 0.75rem;
  border: 1px solid rgba(204, 255, 51, 0.22);
  background: rgba(204, 255, 51, 0.05);
  text-align: center;
}

/* The excerpt above the gate fades out rather than stopping dead, so it
   reads as "there's more" instead of "this post is short". */
.cb-fade {
  position: relative;
  max-height: 7.5rem;
  overflow: hidden;
}

.cb-fade::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 4rem;
  background: linear-gradient(to bottom, rgba(26, 28, 38, 0), #1A1C26);
}

/* ---- Audio player -------------------------------------------------------- */

.cb-player {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-top: 1.25rem;
  padding: 0.9rem 1rem;
  border-radius: 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.03);
}

.cb-play-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid rgba(204, 255, 51, 0.45);
  background: rgba(204, 255, 51, 0.12);
  color: #CCFF33;
  cursor: pointer;
  transition: all 0.25s ease;
}

.cb-play-btn:hover { background: rgba(204, 255, 51, 0.22); }
.cb-play-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.cb-player-bar {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

.cb-player-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: linear-gradient(90deg, #CCFF33, #2EC5FF);
  transition: width 0.1s linear;
}

/* ---- Comments ------------------------------------------------------------ */

.cb-comments { margin-top: 1.75rem; border-top: 1px solid rgba(255, 255, 255, 0.08); padding-top: 1.25rem; }

.cb-comment {
  padding: 0.75rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.cb-comment:last-child { border-bottom: 0; }

.cb-comment-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.63rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(245, 246, 240, 0.4);
}

.cb-comment-body {
  margin-top: 0.35rem;
  font-size: 0.83rem;
  line-height: 1.6;
  color: rgba(245, 246, 240, 0.8);
  overflow-wrap: anywhere;
}

/* ---- Composer (post a confession / write a comment) --------------------- */

.cb-field {
  width: 100%;
  border-radius: 0.6rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.25);
  color: #F5F6F0;
  font-family: inherit;
  font-size: 0.88rem;
  line-height: 1.6;
  padding: 0.7rem 0.85rem;
  transition: border-color 0.25s ease;
}

.cb-field::placeholder { color: rgba(245, 246, 240, 0.3); }
.cb-field:focus { outline: none; border-color: rgba(204, 255, 51, 0.55); }

.cb-label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(245, 246, 240, 0.45);
}

.cb-counter {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.62rem;
  color: rgba(245, 246, 240, 0.35);
}

.cb-counter.is-over { color: #FF7A54; }

.cb-tabs { display: inline-flex; gap: 0.35rem; padding: 0.25rem; border-radius: 9999px; background: rgba(0, 0, 0, 0.3); }

.cb-tab {
  border: 0;
  border-radius: 9999px;
  background: transparent;
  color: rgba(245, 246, 240, 0.5);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.4rem 1rem;
  cursor: pointer;
  transition: all 0.25s ease;
}

.cb-tab[aria-selected='true'] { background: rgba(204, 255, 51, 0.16); color: #E8FFA6; }

.cb-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  user-select: none;
}

.cb-switch-track {
  position: relative;
  width: 38px;
  height: 21px;
  flex-shrink: 0;
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.06);
  transition: all 0.25s ease;
}

.cb-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: rgba(245, 246, 240, 0.55);
  transition: all 0.25s ease;
}

.cb-switch input { position: absolute; opacity: 0; pointer-events: none; }
.cb-switch input:checked + .cb-switch-track { background: rgba(204, 255, 51, 0.25); border-color: rgba(204, 255, 51, 0.6); }
.cb-switch input:checked + .cb-switch-track .cb-switch-thumb { left: 20px; background: #CCFF33; }

.cb-error {
  margin-top: 0.7rem;
  padding: 0.6rem 0.8rem;
  border-radius: 0.5rem;
  border: 1px solid rgba(255, 122, 84, 0.35);
  background: rgba(255, 77, 46, 0.1);
  font-size: 0.76rem;
  line-height: 1.5;
  color: #FFC9B8;
}

.cb-hint {
  margin-top: 0.5rem;
  font-size: 0.7rem;
  line-height: 1.5;
  color: rgba(245, 246, 240, 0.4);
}

/* ---- Recorder ------------------------------------------------------------ */

.cb-rec {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  padding: 1.5rem 1rem;
  border-radius: 0.75rem;
  border: 1px dashed rgba(255, 255, 255, 0.15);
  background: rgba(0, 0, 0, 0.2);
}

.cb-rec-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  border: 1px solid rgba(255, 77, 46, 0.5);
  background: rgba(255, 77, 46, 0.12);
  color: #FF7A54;
  cursor: pointer;
  transition: all 0.25s ease;
}

.cb-rec-btn:hover { background: rgba(255, 77, 46, 0.2); }

.cb-rec-btn[data-recording='true'] {
  border-color: #FF4D2E;
  background: rgba(255, 77, 46, 0.28);
  color: #FFC9B8;
}

/* Only the halo pulses, not the button — a pulsing hit target is hard to
   click, and this still reads as "live" from across the page. */
.cb-rec-btn[data-recording='true']::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid rgba(255, 77, 46, 0.5);
  animation: cbPulse 1.6s ease-out infinite;
}

@keyframes cbPulse {
  0% { transform: scale(0.95); opacity: 0.9; }
  100% { transform: scale(1.35); opacity: 0; }
}

.cb-rec-time {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 1.15rem;
  font-weight: 600;
  color: rgba(245, 246, 240, 0.8);
  font-variant-numeric: tabular-nums;
}

.cb-rec-hint { font-size: 0.7rem; color: rgba(245, 246, 240, 0.4); text-align: center; }

/* ---- Points pill --------------------------------------------------------- */

.cb-points {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border-radius: 9999px;
  border: 1px solid rgba(204, 255, 51, 0.35);
  background: rgba(204, 255, 51, 0.1);
  color: #E8FFA6;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.25rem 0.7rem;
  white-space: nowrap;
}

/* ---- Toast --------------------------------------------------------------- */

.cb-toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: 120;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem 1.1rem;
  border-radius: 9999px;
  border: 1px solid rgba(204, 255, 51, 0.4);
  background: rgba(16, 18, 24, 0.95);
  backdrop-filter: blur(8px);
  color: #E8FFA6;
  font-size: 0.8rem;
  font-weight: 600;
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.9);
  animation: cbToast 0.35s cubic-bezier(0.22, 0.9, 0.32, 1) both;
}

@keyframes cbToast {
  from { opacity: 0; transform: translate(-50%, 14px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* ---- Reduced motion ------------------------------------------------------ */
/* Reduced motion means "don't animate", not "don't change".

   This block used to pin `.cb-note`'s transform with `!important`, which was
   right when the tilt was decorative — but the lift is not decoration any
   more. Notes in the pile overlap on purpose, and lifting one is the only
   way to read the parts covered by its neighbours. Freezing the transform
   left anyone with reduced motion enabled unable to read half the wall.

   So the lift still happens, at full size, instantly. What goes away is the
   travel between the two states, and every ambient animation. */

@media (prefers-reduced-motion: reduce) {
  .cb-note { transition: none; }
  .cb-overlay, .cb-modal, .cb-toast { animation: none; }
  .cb-rec-btn[data-recording='true']::before { animation: none; }
}

/* ==========================================================================
   The archive list (wall.html)

   Deliberately not the corkboard. The board is finite, overlapping and
   physical because it's meant to be looked at; this is the full set and it's
   meant to be read, so it's a plain vertical list with a colour spine
   carrying over the note's paper colour as the only thing tying the two
   views together.
   ========================================================================== */

.cb-list { display: flex; flex-direction: column; gap: 0.7rem; }

.cb-list-row {
  display: flex;
  gap: 0;
  width: 100%;
  padding: 0;
  text-align: left;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0.85rem;
  background: rgba(255, 255, 255, 0.025);
  color: inherit;
  overflow: hidden;
  transition: border-color 0.25s ease, background 0.25s ease, transform 0.25s ease;
}

.cb-list-row:hover {
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.05);
  transform: translateX(2px);
}

.cb-list-row:focus-visible { outline: 2px solid #CCFF33; outline-offset: 2px; }

/* The one thread back to the board: a note's paper colour, as a spine. */
.cb-list-spine {
  width: 4px;
  flex-shrink: 0;
  align-self: stretch;
  background: linear-gradient(180deg, var(--note-bg), var(--note-bg-2));
}

.cb-list-main { flex: 1; min-width: 0; padding: 0.95rem 1.1rem; }

.cb-list-title {
  font-family: 'Rajdhani', ui-sans-serif, sans-serif;
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.2;
  color: #F5F6F0;
  overflow-wrap: anywhere;
}

.cb-list-excerpt {
  margin-top: 0.3rem;
  font-size: 0.83rem;
  line-height: 1.6;
  color: rgba(245, 246, 240, 0.6);
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cb-list-voice {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.35rem;
  font-size: 0.76rem;
  color: rgba(245, 246, 240, 0.55);
}

.cb-list-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  margin-top: 0.55rem;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(245, 246, 240, 0.35);
}

.cb-list-meta svg { width: 11px; height: 11px; vertical-align: -1px; }
