/* ============================================
   THE SECRET DRAWER — interaction engine (Phase 2).

   Styles everything drawer-engine.js renders into
   .tc-secret-drawer__objects: puzzle objects,
   placeholder chips, drop zones, hover hints,
   drag feedback, clue cards and effects.

   Brass/wood custom props (--tc-brass etc.) are
   inherited from the enclosing <footer class="tc-drawer">.
   ============================================ */

/* ----------------------------------------------------------------
   OBJECTS — positioned by the engine via inline left/top/width %
   and a --rot custom property. Centre-anchored so rotation and the
   drag scale-up pivot cleanly. */
.tc-do {
    position: absolute;
    transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
    pointer-events: auto;
    z-index: 2;
    transition: transform 0.25s cubic-bezier(0.34, 1.4, 0.64, 1),
                filter 0.18s ease;
    touch-action: none;          /* the pointer drag owns the gesture */
    -webkit-user-select: none;
    user-select: none;
}
.tc-do img {
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none;
    filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.5));
}
.tc-do.is-draggable { cursor: grab; }
.tc-do.is-draggable:hover {
    filter: brightness(1.08) drop-shadow(0 0 7px rgba(231, 201, 143, 0.6));
}
.tc-do.is-dragging {
    cursor: grabbing;
    transition: none;
    z-index: 50;
    transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(1.12);
}
.tc-do.is-dragging img {
    filter: drop-shadow(0 14px 24px rgba(0, 0, 0, 0.6));
}

/* `classWhen: { "is-lit": "lantern-lit" }` style states — the
   engine adds these classes when their flag is set. Currently
   only the jack-o-lantern uses is-lit, but the rule is generic
   enough that future objects can declare their own glow. */
.tc-do.is-lit img {
    animation: tc-lantern-flicker 1.4s ease-in-out infinite alternate;
}
@keyframes tc-lantern-flicker {
    0%   { filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.5))
                   drop-shadow(0 0  8px rgba(255, 170, 50, 0.55))
                   drop-shadow(0 0 16px rgba(255, 120, 40, 0.35)); }
    50%  { filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.5))
                   drop-shadow(0 0 12px rgba(255, 200, 70, 0.7))
                   drop-shadow(0 0 22px rgba(255, 130, 40, 0.5))
                   brightness(1.05); }
    100% { filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.5))
                   drop-shadow(0 0 18px rgba(255, 220, 90, 0.9))
                   drop-shadow(0 0 32px rgba(255, 150, 50, 0.65))
                   brightness(1.12); }
}
@media (prefers-reduced-motion: reduce) {
    .tc-do.is-lit img { animation: none;
        filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.5))
                drop-shadow(0 0 14px rgba(255, 200, 70, 0.75)); }
}

/* Placeholder chip — an object whose real cutout hasn't been shot
   yet. Reads clearly as "swap me out" but is fully interactive. */
.tc-do.is-placeholder .tc-do__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    padding: 8px 13px;
    border-radius: 6px;
    font-family: Georgia, "Iowan Old Style", serif;
    font-style: italic;
    font-size: 0.8rem;
    color: #f3e8cf;
    background: linear-gradient(180deg, #3a2414 0%, #1a0e07 100%);
    border: 1px dashed rgba(184, 146, 78, 0.7);
    box-shadow: 0 6px 13px rgba(0, 0, 0, 0.5);
}
.tc-do__icon { font-style: normal; font-size: 1.15rem; }

/* ----------------------------------------------------------------
   ZONES — drop targets. A soft dashed well that gently pulses so
   the player can tell something belongs here. */
.tc-zone {
    position: absolute;
    transform: translate(-50%, -50%);
    pointer-events: auto;
    z-index: 1;
    border-radius: 14px;
    border: 2.5px dashed rgba(231, 201, 143, 0.85);
    background: radial-gradient(ellipse at center,
        rgba(231, 201, 143, 0.22) 0%, rgba(231, 201, 143, 0.04) 65%, transparent 80%);
    box-shadow: 0 0 12px rgba(231, 201, 143, 0.3),
                inset 0 0 14px rgba(231, 201, 143, 0.2);
    animation: tc-zone-pulse 2.4s ease-in-out infinite;
}
@keyframes tc-zone-pulse {
    0%, 100% { opacity: 0.6; }
    50%      { opacity: 1; }
}

/* Valid drop target while a matching object is being dragged —
   hold a bright steady glow so the player can see where it goes. */
.tc-zone.is-droptarget,
.tc-do.is-droptarget {
    animation: none;
    opacity: 1;
    outline: 3px solid rgba(231, 201, 143, 0.95);
    outline-offset: 2px;
    box-shadow: 0 0 26px 8px rgba(231, 201, 143, 0.6);
    border-radius: 12px;
}

/* ----------------------------------------------------------------
   HOVER HINT — handwritten label above an object or zone. Objects
   and zones share the .tc-do__hint element. */
.tc-do__hint {
    position: absolute;
    left: 50%;
    bottom: 100%;
    margin-bottom: 9px;
    transform: translate(-50%, 4px);
    white-space: nowrap;
    font-family: 'Caveat', 'Segoe Script', cursive;
    font-size: 1.05rem;
    color: var(--tc-brass-bright, #e7c98f);
    background: rgba(20, 12, 8, 0.96);
    border: 1px solid rgba(184, 146, 78, 0.5);
    padding: 3px 11px 4px;
    border-radius: 4px;
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease;
    z-index: 60;
}
.tc-do:hover > .tc-do__hint,
.tc-zone:hover > .tc-do__hint {
    opacity: 1;
    transform: translate(-50%, 0);
}
.tc-do.is-dragging > .tc-do__hint { opacity: 0 !important; }

/* ----------------------------------------------------------------
   FLASH — a brief warm bloom over the stage; covers a surface swap
   or punctuates a completed step. */
.tc-drawer-flash {
    position: absolute;
    inset: 0;
    border-radius: 6px;
    pointer-events: none;
    z-index: 70;
    background: radial-gradient(ellipse at center,
        rgba(255, 240, 200, 0.85) 0%, rgba(255, 240, 200, 0) 70%);
    animation: tc-flash 0.6s ease-out forwards;
}
@keyframes tc-flash {
    0%   { opacity: 0; }
    25%  { opacity: 1; }
    100% { opacity: 0; }
}

/* ----------------------------------------------------------------
   CRASH — `crash:<id>` action. Full-viewport overlay: the named
   object falls from above with a bouncy entrance, slams centre,
   the screen "cracks" via an SVG of radiating lines, holds for
   a few seconds, then everything fades out. ~5.4s total.

   Layers (all position: fixed, full viewport):
     .tc-crash             dim backdrop, animates in/out
     .tc-crash__obj        the falling image (transform animation)
     .tc-crash__cracks     SVG cracks overlay (fade-in on impact)
*/
.tc-crash {
    position: fixed;
    inset: 0;
    z-index: 99999;
    pointer-events: none;
    overflow: hidden;
    background: rgba(0, 0, 0, 0);
    animation: tc-crash-bg 5.4s ease-out forwards;
}
.tc-crash__obj {
    position: absolute;
    left: 50%;
    top: 50%;
    max-width: 80vw;
    max-height: 80vh;
    transform-origin: center;
    transform: translate(-50%, -200%) rotate(-25deg) scale(0.6);
    filter: drop-shadow(0 30px 60px rgba(0, 0, 0, 0.6));
    animation: tc-crash-fall 5.4s cubic-bezier(0.3, 1.4, 0.55, 1) forwards;
    will-change: transform, opacity;
}
.tc-crash__cracks {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: scale(0.6);
    animation: tc-crash-cracks 5.4s ease forwards;
    will-change: opacity, transform;
}
.tc-crash__cracks svg {
    width: 100%;
    height: 100%;
    display: block;
    filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.7));
}

/* Backdrop dims to ~55%, holds, then fades back to transparent. */
@keyframes tc-crash-bg {
    0%   { background: rgba(0, 0, 0, 0); }
    16%  { background: rgba(0, 0, 0, 0.55); }
    85%  { background: rgba(0, 0, 0, 0.55); }
    100% { background: rgba(0, 0, 0, 0); }
}

/* Duck enters from above, slams down with a small overshoot, holds,
   then fades while drifting slightly upward (relief). */
@keyframes tc-crash-fall {
    0%   { transform: translate(-50%, -200%) rotate(-25deg) scale(0.55); opacity: 0; }
    5%   { opacity: 1; }
    15%  { transform: translate(-50%, -42%)  rotate( 12deg) scale(1.06); }
    18%  { transform: translate(-50%, -50%)  rotate(  6deg) scale(1.00); }
    22%  { transform: translate(-50%, -48%)  rotate(  3deg) scale(1.02); }
    26%  { transform: translate(-50%, -50%)  rotate(  0deg) scale(1.00); }
    85%  { transform: translate(-50%, -50%)  rotate(  0deg) scale(1.00); opacity: 1; }
    100% { transform: translate(-50%, -56%)  rotate(  0deg) scale(1.03); opacity: 0; }
}

/* Cracks appear on impact (~16%), hold, fade out. */
@keyframes tc-crash-cracks {
    0%   { opacity: 0; transform: scale(0.55); }
    14%  { opacity: 0; transform: scale(0.55); }
    18%  { opacity: 1; transform: scale(1); }
    85%  { opacity: 0.92; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
    .tc-crash__obj,
    .tc-crash__cracks { animation-duration: 1.5s; }
    .tc-crash         { animation-duration: 1.5s; }
}

/* ----------------------------------------------------------------
   BUBBLES — `bubbles:true` action. Pearlescent circles rise from
   the bottom of the drawer stage with a slight horizontal sway
   and pop out the top. Pure GPU transform + opacity animation.
   Container sits behind clue cards / modals so the bubbles drift
   serenely behind whatever the player is reading. */
.tc-bubbles {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 65;
    overflow: hidden;
    border-radius: 6px;     /* match the drawer stage rounding */
}
.tc-bubble {
    position: absolute;
    bottom: -40px;
    border-radius: 50%;
    background:
        radial-gradient( ellipse at 32% 28%,
            rgba(255, 255, 255, 0.95) 0%,
            rgba(220, 240, 255, 0.7)  18%,
            rgba(170, 215, 255, 0.42) 42%,
            rgba(100, 180, 230, 0.22) 70%,
            rgba(60, 140, 200, 0.08)  92%,
            transparent 100% );
    box-shadow:
        inset 0 -4px 7px rgba(255, 255, 255, 0.55),
        inset 0  3px 6px rgba(200, 230, 255, 0.45),
        0 0 8px rgba(170, 220, 255, 0.25);
    --travel: 400px;
    --sway:   0px;
    opacity: 0;
    animation: tc-bubble-rise linear forwards;
    will-change: transform, opacity;
}
@keyframes tc-bubble-rise {
    0%   { transform: translate(0, 0) scale(0.5);
           opacity: 0; }
    12%  { opacity: 0.9; transform: translate(0, calc(var(--travel) * -0.05)) scale(1); }
    50%  { opacity: 0.95;
           transform: translate(calc(var(--sway) * 0.6), calc(var(--travel) * -0.55)) scale(1); }
    85%  { opacity: 0.7; }
    100% { transform: translate(var(--sway), calc(var(--travel) * -1)) scale(1.02);
           opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .tc-bubble { animation-duration: 1s !important;
                 animation-delay: 0s !important; opacity: 0.4; }
}

/* ----------------------------------------------------------------
   BLACKHOLE — the astronaut sticker's gag.
   Six-phase cosmic event (~2.8s total):
     0.0 – 0.7s  shake + chromatic aberration tint as the rift opens
     0.7 – 1.4s  swirling accretion disk + event-horizon ring grow
     1.4 – 1.9s  stage collapses into the void; everything black
     1.9 – 2.2s  silent singularity
     2.2 – 2.4s  blinding white flash + rebound impulse
     2.4 – 2.8s  fade back to a clean drawer (sans astronaut)

   The stage itself does the shake + implosion (.tc-fx-blackhole
   class). The cosmic visuals — accretion disk, event horizon, void,
   flash, the sucked-in astronaut — live in a SEPARATE overlay
   element (.tc-fx-blackhole-overlay) appended to the drawer overlay
   so they don't scale to nothing along with the imploding stage. */

.tc-fx-blackhole {
    animation: tc-blackhole-stage 2.8s cubic-bezier(0.72, 0, 0.85, 0.05) both;
    transform-origin: center;
    will-change: transform, filter;
}
@keyframes tc-blackhole-stage {
    /* shake + creeping wrongness */
    0%   { transform: translate(0, 0) scale(1) rotate(0deg);     filter: none; }
    4%   { transform: translate(-6px, 3px) scale(1) rotate(-1.2deg); filter: hue-rotate(-20deg) saturate(1.2); }
    8%   { transform: translate(7px, -4px) scale(1) rotate(1.4deg);  filter: hue-rotate(25deg) saturate(1.3); }
    14%  { transform: translate(-9px, -5px) scale(1.02) rotate(-2deg); filter: hue-rotate(-45deg) saturate(1.6) brightness(1.05); }
    20%  { transform: translate(8px, 6px) scale(1.03) rotate(2deg);   filter: hue-rotate(60deg) saturate(2) brightness(1.1) contrast(1.15); }
    /* getting drawn in — spin + drift toward center, blur ramps */
    35%  { transform: translate(0, 0) scale(1.05) rotate(180deg); filter: hue-rotate(120deg) saturate(2.4) brightness(0.85) blur(1px) contrast(1.2); }
    50%  { transform: translate(0, 0) scale(0.85) rotate(540deg); filter: hue-rotate(180deg) saturate(2.6) brightness(0.55) blur(4px) contrast(1.4); }
    /* violent collapse */
    65%  { transform: scale(0.18) rotate(1080deg); filter: blur(18px) brightness(0.2) saturate(3); }
    72%  { transform: scale(0.005) rotate(1440deg); filter: blur(40px) brightness(0); opacity: 0; }
    /* singularity hold (stage invisible) */
    80%  { transform: scale(0); opacity: 0; }
    /* white-out flash + violent rebound */
    82%  { transform: scale(1.18) rotate(0deg); filter: brightness(2.6) contrast(1.4); opacity: 1; }
    88%  { transform: scale(0.94) rotate(0deg); filter: brightness(1.4) contrast(1.1); opacity: 1; }
    100% { transform: scale(1) rotate(0deg); filter: none; opacity: 1; }
}

.tc-fx-blackhole-overlay {
    position: absolute;
    inset: 0;
    z-index: 95;
    pointer-events: none;
    overflow: hidden;
    background: transparent;
}

/* The accretion disk — a conic-gradient ring of hot plasma swirling
   around the singularity. Masked with a radial gradient so the inner
   black hole is transparent and the outer edge feathers out. */
.tc-fx-blackhole__disk {
    position: absolute;
    left: 50%; top: 50%;
    width: min(82vw, 720px);
    aspect-ratio: 1;
    border-radius: 50%;
    background: conic-gradient(from 0deg,
        rgba(255, 180,  60, 0)    0deg,
        rgba(255, 200,  80, 0.95) 50deg,
        rgba(255, 100, 200, 0.95) 110deg,
        rgba(120,  60, 255, 0.9)  180deg,
        rgba(255,  60,  90, 0.92) 240deg,
        rgba(255, 200,  80, 0.95) 310deg,
        rgba(255, 180,  60, 0)    360deg);
    transform: translate(-50%, -50%) scale(0) rotate(0deg);
    mask-image:           radial-gradient(circle, transparent 28%, #000 38%, #000 88%, transparent 100%);
    -webkit-mask-image:   radial-gradient(circle, transparent 28%, #000 38%, #000 88%, transparent 100%);
    filter: blur(3px) saturate(1.4);
    mix-blend-mode: screen;
    animation: tc-bh-disk 2.8s cubic-bezier(0.55, 0, 0.85, 0.1) forwards;
}
@keyframes tc-bh-disk {
    0%   { transform: translate(-50%, -50%) scale(0)   rotate(0deg);   opacity: 0; }
    10%  { transform: translate(-50%, -50%) scale(0.15) rotate(120deg); opacity: 0.6; }
    35%  { transform: translate(-50%, -50%) scale(0.65) rotate(720deg); opacity: 1;   filter: blur(4px) saturate(1.6) brightness(1.4); }
    60%  { transform: translate(-50%, -50%) scale(1.6)  rotate(1620deg); opacity: 1;  filter: blur(12px) saturate(2) brightness(2); }
    72%  { transform: translate(-50%, -50%) scale(2.4)  rotate(2160deg); opacity: 0;  filter: blur(28px) brightness(3); }
    100% { transform: translate(-50%, -50%) scale(2.4)  rotate(2160deg); opacity: 0; }
}

/* Thin bright event-horizon ring just inside the disk — a hairline
   of pure white that flares as the disk peaks. */
.tc-fx-blackhole__ring {
    position: absolute;
    left: 50%; top: 50%;
    width: min(82vw, 720px);
    aspect-ratio: 1;
    border-radius: 50%;
    box-shadow:
        inset 0 0 0 2px rgba(255, 240, 220, 0),
        0 0 0 0 rgba(255, 200, 120, 0);
    transform: translate(-50%, -50%) scale(0);
    animation: tc-bh-ring 2.8s cubic-bezier(0.55, 0, 0.85, 0.1) forwards;
}
@keyframes tc-bh-ring {
    0%, 25% { box-shadow: inset 0 0 0 2px rgba(255, 240, 220, 0), 0 0 0 0 rgba(255, 200, 120, 0); transform: translate(-50%, -50%) scale(0); }
    40%     { box-shadow: inset 0 0 0 2px rgba(255, 240, 220, 0.9), 0 0 30px 4px rgba(255, 200, 120, 0.7); transform: translate(-50%, -50%) scale(0.35); }
    60%     { box-shadow: inset 0 0 0 3px rgba(255, 250, 235, 1),    0 0 60px 12px rgba(255, 180,  80, 0.95); transform: translate(-50%, -50%) scale(0.95); }
    72%     { box-shadow: inset 0 0 0 1px rgba(255, 250, 235, 0),    0 0 120px 40px rgba(255, 220, 160, 0.9); transform: translate(-50%, -50%) scale(1.8); opacity: 0; }
    100%    { opacity: 0; }
}

/* The void itself — pure black core that grows from a pinprick into
   a screen-engulfing dark. Also the dark vignette that lingers. */
.tc-fx-blackhole__void {
    position: absolute;
    left: 50%; top: 50%;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: radial-gradient(circle,
        #000 0%,
        #0a0010 55%,
        #1a0030 78%,
        rgba(20, 0, 40, 0) 100%);
    transform: translate(-50%, -50%);
    box-shadow:
        0 0 20px 4px rgba(80, 0, 160, 0.4),
        0 0 60px 12px rgba(40, 0,  80, 0.55);
    animation: tc-bh-void 2.8s cubic-bezier(0.55, 0, 0.85, 0.1) forwards;
}
@keyframes tc-bh-void {
    0%   { width: 0;   height: 0;   opacity: 0; }
    15%  { width: 8px; height: 8px; opacity: 0.7; }
    45%  { width: 60px; height: 60px; opacity: 1; }
    65%  { width: 260px; height: 260px; opacity: 1; }
    74%  { width: 220vmax; height: 220vmax; opacity: 1; background: #000; box-shadow: none; }
    82%  { width: 220vmax; height: 220vmax; opacity: 1; background: #000; }
    100% { width: 220vmax; height: 220vmax; opacity: 0; background: #000; }
}

/* Sharp white-out flash at the moment of rebound. */
.tc-fx-blackhole__flash {
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at center,
        #fff 0%,
        #fff 40%,
        rgba(255, 255, 255, 0) 70%);
    opacity: 0;
    animation: tc-bh-flash 2.8s linear forwards;
}
@keyframes tc-bh-flash {
    0%, 81% { opacity: 0; }
    82%     { opacity: 1; }
    87%     { opacity: 0.6; }
    100%    { opacity: 0; }
}

/* The astronaut clone, sucked in. The engine sets --dx / --dy in
   pixels at runtime (distance from sticker centre to overlay centre)
   so the slingshot lands precisely on the singularity regardless of
   where on the drawer the sticker was placed. */
.tc-fx-blackhole__victim {
    position: absolute;
    z-index: 4;
    transform-origin: center;
    will-change: transform, opacity, filter;
    animation: tc-bh-victim 2.1s cubic-bezier(0.55, 0, 0.85, 0.15) forwards;
}
@keyframes tc-bh-victim {
    0%   { transform: translate(0, 0) scale(1) rotate(0deg);                 opacity: 1; filter: none; }
    25%  { transform: translate(calc(var(--dx, 0px) * 0.15), calc(var(--dy, 0px) * 0.15)) scale(1.08) rotate(-18deg); opacity: 1; filter: brightness(1.1); }
    55%  { transform: translate(calc(var(--dx, 0px) * 0.6),  calc(var(--dy, 0px) * 0.6))  scale(0.55) rotate(540deg); opacity: 1; filter: brightness(0.85); }
    78%  { transform: translate(calc(var(--dx, 0px) * 0.92), calc(var(--dy, 0px) * 0.92)) scale(0.15) rotate(1260deg); opacity: 0.65; filter: brightness(0.4) blur(3px); }
    100% { transform: translate(var(--dx, 0px), var(--dy, 0px)) scale(0) rotate(1980deg); opacity: 0; filter: brightness(0) blur(8px); }
}

@media (prefers-reduced-motion: reduce) {
    .tc-fx-blackhole,
    .tc-fx-blackhole__disk,
    .tc-fx-blackhole__ring,
    .tc-fx-blackhole__void,
    .tc-fx-blackhole__flash,
    .tc-fx-blackhole__victim { animation: none; }
    .tc-fx-blackhole-overlay { background: rgba(0, 0, 0, 0.92); }
}

/* ----------------------------------------------------------------
   CLUE CARD — a handwritten note on aged paper, signed. Covers the
   stage with a soft scrim; dismissed by button / Escape / scrim. */
.tc-clue {
    position: absolute;
    inset: 0;
    z-index: 80;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    background: rgba(8, 5, 3, 0.55);
    opacity: 0;
    transition: opacity 0.24s ease;
}
.tc-clue.is-in { opacity: 1; }

.tc-clue__paper {
    position: relative;
    width: min(78vw, 460px);
    padding: 30px 34px 22px;
    color: #2a2316;
    background:
        repeating-linear-gradient(0deg,
            rgba(255, 255, 255, 0.015) 0 26px,
            rgba(120, 90, 40, 0.07) 27px 28px),
        linear-gradient(180deg, #fbf6e7 0%, #f0e4c6 100%);
    border-radius: 3px;
    transform: rotate(-1.4deg) translateY(14px);
    box-shadow: 0 22px 50px rgba(0, 0, 0, 0.6);
    transition: transform 0.3s cubic-bezier(0.16, 0.84, 0.44, 1);
}
.tc-clue.is-in .tc-clue__paper { transform: rotate(-1.4deg) translateY(0); }

.tc-clue__body p {
    margin: 0 0 8px;
    font-family: 'Caveat', 'Segoe Script', cursive;
    font-size: clamp(1.15rem, 2.4vw, 1.5rem);
    line-height: 1.34;
}
.tc-clue__body p:empty { height: 0.5em; margin: 0; }

.tc-clue__sig {
    margin-top: 10px;
    text-align: right;
    color: #3a2a14;
}
.tc-clue__sig svg,
.tc-clue__sig .tc-signature-svg {
    display: inline-block;
    width: 130px;
    height: auto;
}

/* ----------------------------------------------------------------
   BRASS BUTTONS — shared visual language for the clue "got it"
   button and the choice modal buttons. Multi-layer shadow stack
   gives a tactile, slightly-domed feel (top highlight, bottom
   stamping shadow, atmospheric drop). Hover lifts + glows; active
   presses down + cuts the shadow stack. Explicit text colour at
   every state (with -webkit-text-fill-color belt-and-braces) so
   the label can't get hidden by an inherited filter or browser
   rendering quirk. */
.tc-clue__dismiss,
.tc-choice__btn {
    appearance: none;
    cursor: pointer;
    font-family: Georgia, "Iowan Old Style", serif;
    font-size: 0.98rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: #1a0e07;
    -webkit-text-fill-color: #1a0e07;
    text-shadow: 0 1px 0 rgba(255, 240, 200, 0.55);
    background:
        linear-gradient(180deg,
            #f6dfa6 0%,
            #e7c98f 48%,
            #c89a52 100%);
    border: 1px solid #6b4d22;
    border-top-color: #f3deb3;
    border-radius: 6px;
    padding: 11px 22px 12px;
    box-shadow:
        inset 0 1px 0 rgba(255, 240, 200, 0.75),
        inset 0 -1px 0 rgba(80, 50, 16, 0.35),
        0 1px 0 #4a3416,
        0 4px 0 #3a2a12,
        0 8px 16px rgba(0, 0, 0, 0.42);
    transition:
        transform 0.14s cubic-bezier(0.34, 1.4, 0.64, 1),
        box-shadow 0.2s ease,
        filter 0.2s ease,
        background-position 0.2s ease;
}
.tc-clue__dismiss:hover,
.tc-choice__btn:hover {
    transform: translateY(-2px);
    filter: brightness(1.08) saturate(1.08);
    color: #1a0e07;
    -webkit-text-fill-color: #1a0e07;
    box-shadow:
        inset 0 1px 0 rgba(255, 250, 215, 0.85),
        inset 0 -1px 0 rgba(80, 50, 16, 0.35),
        0 1px 0 #4a3416,
        0 6px 0 #3a2a12,
        0 14px 24px rgba(0, 0, 0, 0.5),
        0 0 18px rgba(231, 201, 143, 0.55);
}
.tc-clue__dismiss:active,
.tc-choice__btn:active {
    transform: translateY(2px);
    filter: brightness(1.04);
    box-shadow:
        inset 0 1px 0 rgba(255, 240, 200, 0.5),
        inset 0 -1px 0 rgba(80, 50, 16, 0.45),
        0 1px 0 #4a3416,
        0 2px 0 #3a2a12,
        0 4px 8px rgba(0, 0, 0, 0.35);
}
.tc-clue__dismiss:focus-visible,
.tc-choice__btn:focus-visible {
    outline: 2px solid #f3deb3;
    outline-offset: 3px;
}

/* Choice buttons sit in a 2-up grid; give them a touch more
   presence than the lone "got it" button. */
.tc-choice__btn {
    font-size: 1.05rem;
    padding: 13px 16px 14px;
}

/* ----------------------------------------------------------------
   REDUCED MOTION. */
@media (prefers-reduced-motion: reduce) {
    .tc-do,
    .tc-clue,
    .tc-clue__paper { transition: none; }
    .tc-zone { animation: none; opacity: 0.72; }
    .tc-drawer-flash { animation-duration: 0.2s; }
    .tc-clue__paper { transform: rotate(-1.4deg); }
}

/* ----------------------------------------------------------------
   AUTHOR MODE (?author) — a layout toolbar plus free-drag
   affordances on every object and zone. */
.tc-author-bar {
    position: fixed;
    left: 50%;
    bottom: 14px;
    transform: translateX(-50%);
    z-index: 10000;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    max-width: 96vw;
    padding: 8px 13px;
    background: rgba(20, 12, 8, 0.96);
    border: 1px solid rgba(184, 146, 78, 0.6);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
    font-family: Georgia, "Iowan Old Style", serif;
    font-size: 0.8rem;
    color: var(--tc-brass-bright, #e7c98f);
}
.tc-author-bar strong { letter-spacing: 0.08em; }
.tc-author-bar__hint { font-style: italic; opacity: 0.7; }
.tc-author-bar button {
    appearance: none;
    cursor: pointer;
    font: inherit;
    color: #1a0e07;
    background: linear-gradient(180deg,
        var(--tc-brass-bright, #e7c98f), var(--tc-brass, #b8924e));
    border: 1px solid #6b4d22;
    border-radius: 5px;
    padding: 5px 12px 6px;
}
.tc-author-bar__surface {
    background: transparent !important;
    color: var(--tc-brass-bright, #e7c98f) !important;
    border-color: rgba(184, 146, 78, 0.4) !important;
    font-size: 0.72rem;
}
.tc-author-bar__surface:hover { border-color: rgba(184, 146, 78, 0.95) !important; }

/* Every object + zone is grab-draggable while authoring. Transitions
   are KILLED in author mode so the visual position is always
   instantaneously what `style.left/top` says — no animation, no
   interpolation, no risk of a visible snap-back artifact. */
.tc-do.is-author,
.tc-zone.is-author { cursor: grab; transition: none !important; }
.tc-do.is-author.is-dragging,
.tc-zone.is-author.is-dragging { cursor: grabbing; }
.tc-do.is-author:hover {
    filter: brightness(1.1) drop-shadow(0 0 8px rgba(231, 201, 143, 0.7));
}
/* Zones don't pulse in author mode — held steady for placing. */
.tc-zone.is-author { animation: none; opacity: 0.55; }
.tc-zone.is-author:hover { opacity: 0.9; }
/* Things not "shown" at start render dimmed, so it's clear they're
   off by default but still placeable. */
.tc-do.is-author-hidden,
.tc-zone.is-author.is-author-hidden { opacity: 0.38; }
.tc-do.is-author-hidden:hover,
.tc-zone.is-author.is-author-hidden:hover { opacity: 0.85; }

/* The id tag pinned under each object/zone. */
.tc-author-tag {
    position: absolute;
    left: 50%;
    top: 100%;
    transform: translate(-50%, 4px);
    white-space: nowrap;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 10px;
    color: #1a0e07;
    background: rgba(231, 201, 143, 0.92);
    padding: 1px 5px;
    border-radius: 3px;
    pointer-events: none;
    z-index: 61;
}

/* ----------------------------------------------------------------
   VIDEO PLAYER OVERLAY — `video:<id>` action. Centred, dim scrim.
   The Faberge reveal lives here; future video payoffs reuse it. */
.tc-drawer-video {
    position: absolute;
    inset: 0;
    z-index: 85;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vw;
    background: rgba(4, 3, 2, 0.78);
    opacity: 0;
    transition: opacity 0.22s ease;
}
.tc-drawer-video.is-in { opacity: 1; }
.tc-drawer-video video {
    width: 100%;
    max-width: 92vw;
    max-height: 86vh;
    background: #000;
    border-radius: 4px;
    box-shadow: 0 18px 60px rgba(0, 0, 0, 0.75);
}
.tc-drawer-youtube iframe {
    width: min(92vw, 1100px);
    aspect-ratio: 16 / 9;
    max-height: 86vh;
    background: #000;
    border: 0;
    border-radius: 4px;
    box-shadow: 0 18px 60px rgba(0, 0, 0, 0.75);
}

/* ----------------------------------------------------------------
   FULLSCREEN STAGE — `fullscreen:<id>` action. Lives at body root
   (not inside the drawer overlay) so requestFullscreen escalates
   to the WHOLE browser viewport, not just the drawer rectangle.
   The giant duck head lives here. */
.tc-drawer-fullscreen {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;
    cursor: pointer;
}
.tc-drawer-fullscreen img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;     /* never crop — Thomas's rule */
    pointer-events: none;
    filter: drop-shadow(0 22px 50px rgba(255, 255, 255, 0.18));
}
/* When fullscreen is actually granted, fill the screen exactly. */
.tc-drawer-fullscreen:fullscreen { background: #000; }

/* ----------------------------------------------------------------
   PASSCODE PAD — `passcode:` action. The Ledger Wallet's gate. A
   blocky calculator-style pad on the same aged-paper stock as the
   clue card, so the puzzle's tactile vocabulary stays consistent. */
.tc-passcode {
    position: absolute;
    inset: 0;
    z-index: 82;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(8, 5, 3, 0.6);
    opacity: 0;
    transition: opacity 0.22s ease;
}
.tc-passcode.is-in { opacity: 1; }
.tc-passcode__paper {
    width: min(78vw, 320px);
    padding: 22px 22px 26px;
    color: #2a2316;
    background: linear-gradient(180deg, #fbf6e7 0%, #eadfba 100%);
    border-radius: 6px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, 0.65);
    transform: rotate(-1deg) translateY(10px);
    transition: transform 0.28s cubic-bezier(0.16, 0.84, 0.44, 1);
}
.tc-passcode.is-in .tc-passcode__paper { transform: rotate(-1deg) translateY(0); }
.tc-passcode__screen {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 1.7rem;
    letter-spacing: 0.4em;
    text-align: center;
    padding: 10px 0 14px;
    color: #1a0e07;
    border-bottom: 1px dashed rgba(80, 60, 30, 0.45);
    margin-bottom: 14px;
    transition: color 0.15s ease, transform 0.15s ease;
}
.tc-passcode__screen.is-bad {
    color: #a33;
    animation: tc-passcode-shake 0.34s ease;
}
@keyframes tc-passcode-shake {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-6px); }
    50%      { transform: translateX(5px); }
    75%      { transform: translateX(-3px); }
}
.tc-passcode__pad {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 9px;
}
.tc-passcode__key {
    appearance: none;
    cursor: pointer;
    font: inherit;
    font-size: 1.1rem;
    color: #1a0e07;
    background: linear-gradient(180deg, #f6ecd0 0%, #d8c694 100%);
    border: 1px solid #b8924e;
    border-radius: 5px;
    padding: 11px 0;
    box-shadow: 0 3px 0 #97743a;
    transition: transform 0.08s ease, box-shadow 0.08s ease;
}
.tc-passcode__key:active {
    transform: translateY(2px);
    box-shadow: 0 1px 0 #97743a;
}

@media (prefers-reduced-motion: reduce) {
    .tc-drawer-video,
    .tc-passcode,
    .tc-passcode__paper { transition: none; }
    .tc-passcode__paper { transform: rotate(-1deg); }
    .tc-passcode__screen.is-bad { animation: none; }
}

/* ----------------------------------------------------------------
   RADIO STREAM WIDGET — `stream:` action. A small persistent bar
   docked at the bottom of the drawer overlay; one station at a
   time, switches hard-cut. Brass/wood vocabulary so it reads as
   a real little radio. */
.tc-drawer-stream {
    position: absolute;
    left: 50%;
    bottom: 14px;
    transform: translateX(-50%);
    z-index: 86;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: linear-gradient(180deg, #2a1a0c 0%, #14090a 100%);
    border: 1px solid rgba(184, 146, 78, 0.6);
    border-radius: 8px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
    font-family: Georgia, "Iowan Old Style", serif;
    color: var(--tc-brass-bright, #e7c98f);
    font-size: 0.88rem;
    max-width: 92vw;
}
.tc-stream__label {
    white-space: nowrap;
    font-style: italic;
    letter-spacing: 0.02em;
    padding-right: 4px;
}
.tc-stream__btn {
    appearance: none;
    cursor: pointer;
    background: linear-gradient(180deg, #5a3f1c 0%, #2a1a0c 100%);
    border: 1px solid rgba(184, 146, 78, 0.7);
    color: var(--tc-brass-bright, #e7c98f);
    width: 30px;
    height: 30px;
    border-radius: 4px;
    font-size: 0.95rem;
    line-height: 1;
    padding: 0;
    transition: transform 0.08s ease;
}
.tc-stream__btn:hover { transform: translateY(-1px); }
.tc-stream__btn:active { transform: translateY(0); }
.tc-stream__vol {
    width: 86px;
    accent-color: var(--tc-brass, #b8924e);
}

/* ----------------------------------------------------------------
   CHOICE MODAL — `choice:` action. Prompt + N buttons on the same
   aged-paper stock. The Golden-Egg fork lives here. */
.tc-choice {
    position: absolute;
    inset: 0;
    z-index: 84;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(8, 5, 3, 0.6);
    opacity: 0;
    transition: opacity 0.22s ease;
}
.tc-choice.is-in { opacity: 1; }
.tc-choice__paper {
    width: min(86vw, 440px);
    padding: 22px 26px 24px;
    color: #2a2316;
    background: linear-gradient(180deg, #fbf6e7 0%, #eadfba 100%);
    border-radius: 6px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, 0.65);
    transform: rotate(-0.6deg) translateY(10px);
    transition: transform 0.28s cubic-bezier(0.16, 0.84, 0.44, 1);
}
.tc-choice.is-in .tc-choice__paper { transform: rotate(-0.6deg) translateY(0); }
.tc-choice__prompt {
    margin-bottom: 16px;
    text-align: center;
}
.tc-choice__prompt p {
    margin: 0 0 6px;
    font-family: 'Caveat', 'Segoe Script', cursive;
    font-size: clamp(1.1rem, 2.4vw, 1.4rem);
    line-height: 1.34;
    color: #2a2316;
}
.tc-choice__btns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
/* `.tc-choice__btn` styles live up top, shared with .tc-clue__dismiss. */
@media (prefers-reduced-motion: reduce) {
    .tc-choice, .tc-choice__paper { transition: none; }
    .tc-choice__paper { transform: rotate(-0.6deg); }
}

/* ----------------------------------------------------------------
   HANGMAN MINI-GAME — `hangman:true` action. Sticky-note paper +
   monospace gallows + A-Z keyboard. Lives are wrong-guess count
   (6 = noose), word picked from P.hangman[currentMonth]. Tactile
   vocabulary matches the clue card and passcode pad. */
.tc-hangman {
    position: absolute;
    inset: 0;
    z-index: 82;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(8, 5, 3, 0.6);
    opacity: 0;
    transition: opacity 0.22s ease;
}
.tc-hangman.is-in { opacity: 1; }

.tc-hangman__paper {
    width: min(94vw, 460px);
    max-height: 96vh;
    overflow-y: auto;
    padding: 20px 22px 22px;
    color: #2a2316;
    background: linear-gradient(180deg, #fbf6e7 0%, #eadfba 100%);
    border-radius: 6px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, 0.65);
    transform: rotate(-0.6deg) translateY(10px);
    transition: transform 0.28s cubic-bezier(0.16, 0.84, 0.44, 1);
}
.tc-hangman.is-in .tc-hangman__paper { transform: rotate(-0.6deg) translateY(0); }

.tc-hangman__gallows {
    margin: 0 0 8px;
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    font-size: clamp(0.85rem, 1.6vw, 1.05rem);
    line-height: 1.05;
    text-align: center;
    color: #1a0e07;
    white-space: pre;
}
.tc-hangman__word {
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    font-size: clamp(1.2rem, 2.6vw, 1.7rem);
    letter-spacing: 0.18em;
    text-align: center;
    padding: 8px 0 10px;
    color: #1a0e07;
    border-bottom: 1px dashed rgba(80, 60, 30, 0.45);
}
.tc-hangman__used {
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    font-size: 0.85rem;
    text-align: center;
    color: #6a5436;
    padding: 8px 0 12px;
    min-height: 1.5em;
}
.tc-hangman__keys {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 5px;
}
.tc-hangman__key {
    appearance: none;
    cursor: pointer;
    font: inherit;
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    font-size: 0.95rem;
    color: #1a0e07;
    background: linear-gradient(180deg, #f6ecd0 0%, #d8c694 100%);
    border: 1px solid #b8924e;
    border-radius: 4px;
    padding: 6px 0;
    box-shadow: 0 2px 0 #97743a;
    transition: transform 0.08s ease, box-shadow 0.08s ease, opacity 0.18s ease;
}
.tc-hangman__key:active {
    transform: translateY(1px);
    box-shadow: 0 1px 0 #97743a;
}
.tc-hangman__key:disabled {
    cursor: default;
    opacity: 0.45;
}
.tc-hangman__key.is-hit {
    background: linear-gradient(180deg, #cfe4b3 0%, #95b96b 100%);
    border-color: #547839;
    box-shadow: 0 2px 0 #3a5325;
    opacity: 1;
}
.tc-hangman__key.is-miss {
    background: linear-gradient(180deg, #ecc7c0 0%, #bb6b62 100%);
    border-color: #7c3a35;
    box-shadow: 0 2px 0 #56241f;
    opacity: 0.85;
}

@media (prefers-reduced-motion: reduce) {
    .tc-hangman,
    .tc-hangman__paper { transition: none; }
    .tc-hangman__paper { transform: rotate(-0.6deg); }
}

/* ----------------------------------------------------------------
   PAC-MAN MODAL — `pacman:true` action. CRT phosphor aesthetic to
   match the desk arcade. Reuses desk-games.js's startPacman game
   loop wholesale; we just mount the canvas + HUD. */
.tc-pacman {
    position: absolute;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px;
    background: rgba(0, 0, 0, 0.88);
    opacity: 0;
    transition: opacity 0.22s ease;
}
.tc-pacman.is-in { opacity: 1; }
.tc-pacman__stage {
    background: #000;
    border: 2px solid #2050ff;
    border-radius: 6px;
    padding: 12px 14px 14px;
    color: #ffe200;
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    box-shadow: 0 0 32px rgba(32, 80, 255, 0.45),
                0 18px 50px rgba(0, 0, 0, 0.7);
    max-width: 96vw;
    max-height: 96vh;
    overflow: auto;
}
.tc-pacman__hud {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 10px;
    font-size: 0.9rem;
}
.tc-pacman__title { font-size: 1.1rem; font-weight: bold; letter-spacing: 0.1em; }
.tc-pacman__score { margin-left: auto; color: #fff5d0; }
.tc-pacman__score b { color: #ffe200; }
.tc-pacman__close {
    appearance: none;
    background: transparent;
    border: 1px solid #ffe200;
    color: #ffe200;
    cursor: pointer;
    border-radius: 3px;
    padding: 2px 9px 3px;
    font-family: inherit;
    line-height: 1;
}
.tc-pacman__close:hover { background: rgba(255, 226, 0, 0.15); }
.tc-pacman__canvas {
    display: block;
    image-rendering: pixelated;
    background: #000;
    /* The game's startPacman sets canvas.width/height directly (14
       cols × 13 rows × 26px = 364×338). Let the canvas keep its
       intrinsic pixel size but cap visually to the modal width. */
    max-width: 100%;
    height: auto;
}
.tc-pacman__controls {
    text-align: center;
    margin-top: 8px;
    color: #80f8ff;
    font-size: 0.82rem;
}
.tc-pacman__gameover {
    margin-top: 12px;
    text-align: center;
    background: rgba(255, 226, 0, 0.06);
    border: 1px solid rgba(255, 226, 0, 0.35);
    border-radius: 4px;
    padding: 12px;
}
.tc-pacman__msg   { color: #ff5588; margin-bottom: 4px; font-weight: bold; }
.tc-pacman__final { color: #fff5d0; margin-bottom: 12px; }
.tc-pacman__final b { color: #ffe200; }
.tc-pacman__btns  { display: flex; justify-content: center; gap: 10px; }
.tc-pacman__btn {
    appearance: none;
    cursor: pointer;
    font: inherit;
    font-family: ui-monospace, "Menlo", "Consolas", monospace;
    background: linear-gradient(180deg, #ffe200 0%, #c89a00 100%);
    border: 1px solid #806000;
    color: #1a0e07;
    padding: 7px 14px 8px;
    font-weight: bold;
    border-radius: 4px;
    letter-spacing: 0.03em;
    transition: transform 0.1s ease, filter 0.15s ease;
}
.tc-pacman__btn:hover { filter: brightness(1.1); transform: translateY(-1px); }
.tc-pacman__btn:active { transform: translateY(1px); }
.tc-pacman__credits {
    margin-top: 10px;
    text-align: center;
    color: rgba(255, 245, 208, 0.4);
    font-size: 0.7rem;
    letter-spacing: 0.02em;
}
.tc-pacman__credits a {
    color: rgba(255, 245, 208, 0.5);
    text-decoration: underline;
    text-decoration-style: dotted;
}
.tc-pacman__credits a:hover { color: rgba(255, 245, 208, 0.85); }
@media (prefers-reduced-motion: reduce) {
    .tc-pacman { transition: none; }
    .tc-pacman__btn { transition: none; }
}

/* ----------------------------------------------------------------
   ANCIENT SCROLL — `scroll:<url>` action. The BIC + rolled-scroll
   combine (chain 4) burns the wax seal and the Bitcoin whitepaper
   unfurls in-puzzle as a parchment scroll: two wooden spindle caps
   top + bottom, a scrollable cream parchment middle that renders
   the PDF page-by-page via lazy-loaded PDF.js. Replaces the prior
   `link:` action that opened the PDF in a new browser tab — the
   tab popup broke the puzzle's spell and was awkward on mobile.

   Visual stack:
     .tc-drawer-scroll                (full overlay backdrop)
     └─ .tc-drawer-scroll__paper      (centered scroll container)
         ├─ .tc-drawer-scroll__cap--top    (wooden dowel + brass bands)
         ├─ .tc-drawer-scroll__parchment   (scrollable text area)
         │   └─ canvas.tc-drawer-scroll__page (one per PDF page)
         └─ .tc-drawer-scroll__cap--bottom (wooden dowel + brass bands)
   The scroll "unfurls" via a scaleY transition from the centre. */
.tc-drawer-scroll {
    position: absolute;
    inset: 0;
    z-index: 86;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 28px 16px;
    background: radial-gradient(ellipse at center,
        rgba(20, 12, 4, 0.86) 0%,
        rgba(8, 4, 0, 0.96) 100%);
    opacity: 0;
    transition: opacity 0.28s ease;
}
.tc-drawer-scroll.is-in { opacity: 1; }

.tc-drawer-scroll__paper {
    position: relative;
    width: min(720px, 96%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    transform: scaleY(0.08);
    transform-origin: center;
    transition: transform 0.55s cubic-bezier(0.32, 1.45, 0.55, 1);
    filter: drop-shadow(0 24px 36px rgba(0, 0, 0, 0.65));
}
.tc-drawer-scroll.is-in .tc-drawer-scroll__paper {
    transform: scaleY(1);
}

/* Wooden spindle dowel — a horizontal cylinder. Layered linear
   gradients give the cylindrical curvature; the inset box-shadows
   paint the brass end-bands without needing extra elements. The
   negative horizontal margin lets each cap overhang the parchment
   so the rod reads as a real wooden dowel, not a rounded edge. */
.tc-drawer-scroll__cap {
    flex: 0 0 auto;
    height: 38px;
    margin: 0 -22px;
    border-radius: 19px;
    background:
        linear-gradient(180deg,
            rgba(255, 230, 180, 0.45) 0%,
            rgba(255, 230, 180, 0.05) 22%,
            rgba(0, 0, 0, 0)          50%,
            rgba(0, 0, 0, 0.55)       100%),
        linear-gradient(180deg,
            #5a3a1c 0%,
            #7a4f24 30%,
            #4a2f15 65%,
            #2c1a0a 100%);
    box-shadow:
        inset 18px 0 0 -3px #6e4a18,
        inset -18px 0 0 -3px #6e4a18,
        inset 22px 0 0 -4px #b5933d,
        inset -22px 0 0 -4px #b5933d,
        0 4px 6px rgba(0, 0, 0, 0.45);
    position: relative;
    z-index: 2;
}
.tc-drawer-scroll__cap--top    { border-radius: 19px 19px 6px 6px; }
.tc-drawer-scroll__cap--bottom { border-radius: 6px 6px 19px 19px; }

/* The parchment — aged cream, vignetted edges via inset shadows.
   Scrollable on overflow. Rendered PDF pages stack inside. */
.tc-drawer-scroll__parchment {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 18px 22px;
    background:
        repeating-linear-gradient(180deg,
            rgba(120, 80, 30, 0)    0px,
            rgba(120, 80, 30, 0)    160px,
            rgba(120, 80, 30, 0.04) 161px,
            rgba(120, 80, 30, 0)    162px),
        radial-gradient(ellipse at center,
            #f4e3bf 0%,
            #e8d099 65%,
            #c9a86a 100%);
    box-shadow:
        inset 0 0  60px rgba(80, 50, 10, 0.45),
        inset 0 8px 24px rgba(60, 35, 0, 0.4),
        inset 0 -8px 24px rgba(60, 35, 0, 0.4);
    color: #3a2410;
    -webkit-overflow-scrolling: touch;
}

/* Each rendered PDF page sits on the parchment. Sepia + multiply
   blend so the stark whitepaper turns the cream of aged paper
   rather than punching through as a bright rectangle. */
.tc-drawer-scroll__page {
    display: block;
    width: 100%;
    height: auto;
    margin: 0 auto 14px;
    background: transparent;
    filter: sepia(0.65) contrast(0.95) brightness(0.97);
    mix-blend-mode: multiply;
}
.tc-drawer-scroll__page:last-child { margin-bottom: 0; }

.tc-drawer-scroll__loading,
.tc-drawer-scroll__error {
    font-family: 'Caveat', cursive;
    font-size: 1.6rem;
    text-align: center;
    padding: 40px 20px;
    color: #6a4818;
}

.tc-drawer-scroll__exit {
    position: absolute;
    top: 12px;
    right: 14px;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(30, 18, 8, 0.7);
    border: 1px solid rgba(184, 146, 78, 0.5);
    color: #e8d099;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    z-index: 3;
    transition: background 0.18s ease, transform 0.18s ease;
}
.tc-drawer-scroll__exit:hover,
.tc-drawer-scroll__exit:focus-visible {
    background: rgba(184, 146, 78, 0.85);
    color: #1a0e04;
    transform: scale(1.08);
    outline: none;
}

@media (prefers-reduced-motion: reduce) {
    .tc-drawer-scroll,
    .tc-drawer-scroll__paper { transition: none; }
    .tc-drawer-scroll__paper { transform: scaleY(1); }
}
