/* =============================================================================
   THE LIVING CABINET — San Francisco Vintage, Angels Camp
   =============================================================================

   The interaction language for the Angels Camp side. A living Victorian cabinet
   of curiosities: 19th-century mercantile, apothecary drawer, natural-history
   case, botanical specimen archive, run through a contemporary gallery and a
   modern shop.

   WHAT IT IS NOT, and these are the failure modes to check every build against:
     · not a theme-park Western
     · not a haunted house
     · not sepia nostalgia
     · not cluttered Victorian pastiche

   The test: strip the motion and the botanical layer out and what remains
   should still look like San Francisco Vintage. Lime carries the brand. The
   Victorian is atmosphere on top of a contemporary object, never a costume
   replacing it.

   Depends on the tokens in sfv.css. Extends, never redefines.
   ========================================================================== */

:root{
  /* ---- LAYER SCALE -------------------------------------------------------
     The audit found z-index values of 1, 2, 59, 60, 100, 150, 200, 300, 400,
     500, 900, 901, 1000, 5000, 9000 and 9999 in use. That is what happens
     without a scale: everyone reaches for a bigger number. This is the scale.
     Nothing in the Living Cabinet uses a raw z-index.                        */
  --z-base:        1;
  --z-raised:      10;    /* a card lifting off the shelf                     */
  --z-sticky:     400;    /* the nav, already in use at this value            */
  --z-scrim:      900;    /* the dim behind an overlay, already in use        */
  --z-overlay:    901;    /* examine mode, drawers, the bag                   */
  --z-toast:      950;
  --z-threshold: 1000;    /* the door. Above the site, below nothing.         */

  /* ---- MOTION ------------------------------------------------------------
     sfv.css already defines --dur-fast .15s, --dur .22s, --dur-slow .32s,
     --dur-page .45s and --ease. These are the additions the cabinet needs
     and nothing more. One easing family, so everything feels like one hand. */
  --dur-examine:  .38s;   /* an object coming forward                         */
  --dur-drawer:   .52s;   /* a drawer has mass and travel                     */
  --dur-door:    1.6s;    /* the threshold swing                              */

  --ease-out:     cubic-bezier(.2,.8,.2,1);      /* the house curve           */
  --ease-in:      cubic-bezier(.6,.05,.9,.4);    /* leaving, closing          */
  --ease-weight:  cubic-bezier(.34,.02,.18,1);   /* things with mass          */
  --ease-latch:   cubic-bezier(.2,1.5,.4,1);     /* a mechanism catching      */

  /* ---- DEPTH -------------------------------------------------------------
     Three steps, no more. A cabinet has a shelf, a lift and a hand.          */
  --lift-1: 0 1px 2px rgba(20,18,16,.07), 0 3px 10px rgba(20,18,16,.05);
  --lift-2: 0 2px 6px rgba(20,18,16,.09), 0 12px 32px rgba(20,18,16,.11);
  --lift-3: 0 8px 20px rgba(20,18,16,.14), 0 34px 80px rgba(20,18,16,.22);

  --glass: rgba(255,245,229,.06);
  --rule-c: rgba(20,18,16,.14);
}

/* ==========================================================================
   1. ARTIFACT CARD
   One component for an object, a photograph, a document or a story. The
   product card on the shop page is the same idea and will inherit this in a
   later sprint; it is deliberately left alone for now because it is carrying
   commerce.
   States: rest, hover/focus, lift, open, expanded.
   ========================================================================== */
.artifact{
  position:relative; display:block; width:100%; text-align:left;
  background:var(--paper,#faf3e6); border:1px solid var(--rule-c);
  border-radius:var(--radius,0); padding:0; cursor:pointer;
  color:inherit; font:inherit;
  box-shadow:var(--lift-1);
  transition:transform var(--dur) var(--ease-out),
             box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out);
  transform-origin:center 90%;
}
.artifact:hover,
.artifact:focus-visible{
  transform:translateY(-3px);
  box-shadow:var(--lift-2);
  border-color:rgba(20,18,16,.3);
}
.artifact:active{ transform:translateY(-1px); transition-duration:var(--dur-fast); }
.artifact.is-open{ transform:translateY(-3px); box-shadow:var(--lift-2); }

.artifact-plate{
  position:relative; overflow:hidden; background:var(--stone,#f3e8d4);
  aspect-ratio:4/5;
}
.artifact-plate img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform var(--dur-slow) var(--ease-out);
}
.artifact:hover .artifact-plate img{ transform:scale(1.03); }

/* The specimen label. The one place the natural-history reference is literal. */
.artifact-label{ padding:16px 18px 18px; }
.artifact-kind{
  font-family:'Rosario',sans-serif; font-size:.58rem; letter-spacing:.2em;
  text-transform:uppercase; font-weight:700; color:var(--antique-gold,#7c5c1d);
  margin-bottom:7px; display:block;
}
.artifact-title{
  font-family:'Abril Fatface',serif; font-weight:400; font-size:1.05rem;
  line-height:1.2; margin:0 0 6px; text-wrap:balance;
}
.artifact-meta{
  font-family:'Rosario',sans-serif; font-size:.78rem; color:var(--charcoal,#524b43);
  line-height:1.5;
}

/* A card that has something behind it says so, quietly and only on approach. */
.artifact[data-examine] .artifact-plate::after{
  content:''; position:absolute; right:12px; bottom:12px; width:26px; height:26px;
  border:1px solid var(--ink,#141210); background:var(--sfv-lime,#d2e113);
  opacity:0; transform:scale(.7) rotate(-8deg);
  transition:opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-latch);
  -webkit-mask:var(--examine-glyph) center/14px no-repeat;
          mask:var(--examine-glyph) center/14px no-repeat;
  background-color:var(--sfv-lime,#d2e113);
}
.artifact:hover .artifact-plate::after,
.artifact:focus-visible .artifact-plate::after{ opacity:1; transform:none; }

/* ==========================================================================
   2. EXAMINE MODE
   An artifact comes forward and the room recedes. Generalised from the shop
   page's detail pane, which already proved the pattern under real use.
   ========================================================================== */
.exam-scrim{
  position:fixed; inset:0; z-index:var(--z-scrim);
  background:rgba(20,18,16,.74); backdrop-filter:blur(4px);
  opacity:0; visibility:hidden;
  transition:opacity var(--dur-examine) var(--ease-out), visibility var(--dur-examine);
}
.exam-scrim.is-on{ opacity:1; visibility:visible; }

.exam{
  position:fixed; z-index:var(--z-overlay);
  inset:auto 0 0 0; height:min(92vh,100%);
  background:var(--ivory,#fff5e5);
  display:flex; flex-direction:column;
  transform:translateY(100%);
  transition:transform var(--dur-examine) var(--ease-out);
  box-shadow:var(--lift-3);
}
.exam.is-on{ transform:none; }

/* The panel closes by sliding away, which hides it from the eye but not from
   the keyboard: `display:flex` here overrides the `hidden` attribute the script
   sets, so a closed Examine panel stayed in the tab order. Measured: six tab
   stops landed on a close button and two links nobody could see.

   The script sets `hidden` only after the slide finishes, so taking it out of
   the layout at that point costs no animation and restores honest focus order. */
.exam[hidden],
.exam-scrim[hidden]{ display:none; }
@media(min-width:860px){
  /* On a desk it arrives from the side, like something set down beside you. */
  .exam{ inset:0 0 0 auto; width:min(720px,100%); height:100%;
         transform:translateX(100%); border-left:1px solid var(--rule-c); }
}

.exam-bar{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:14px 18px; border-bottom:1px solid var(--rule-c); flex:0 0 auto;
  background:var(--paper,#faf3e6);
}
.exam-kind{
  font-family:'Rosario',sans-serif; font-size:.58rem; letter-spacing:.2em;
  text-transform:uppercase; font-weight:700; color:var(--antique-gold,#7c5c1d);
}
.exam-close{
  min-width:var(--tap,44px); min-height:var(--tap,44px);
  display:grid; place-items:center; background:none; border:1px solid var(--rule-c);
  cursor:pointer; font-size:1.3rem; line-height:1; color:var(--ink,#141210);
  transition:background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.exam-close:hover{ background:var(--sfv-lime,#d2e113); border-color:var(--ink,#141210); }

.exam-body{ flex:1 1 auto; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }

/* ---- the viewing stage: zoom and pan live here --------------------------- */
.exam-stage{
  position:relative; background:var(--stone,#f3e8d4); overflow:hidden;
  aspect-ratio:4/3; touch-action:none; cursor:zoom-in;
}
.exam-stage.is-zoomed{ cursor:grab; }
.exam-stage.is-panning{ cursor:grabbing; }
.exam-stage img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:contain;
  transform-origin:0 0; will-change:transform;
  transition:transform var(--dur-slow) var(--ease-out);
}
.exam-stage.is-panning img{ transition:none; }

.exam-zoomui{
  position:absolute; right:12px; bottom:12px; display:flex; gap:6px;
}
.exam-zoomui button{
  min-width:var(--tap,44px); min-height:var(--tap,44px);
  background:rgba(20,18,16,.82); color:var(--ivory,#fff5e5);
  border:1px solid rgba(255,245,229,.25); cursor:pointer;
  font-family:'Rosario',sans-serif; font-size:1rem; line-height:1;
  transition:background var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}
.exam-zoomui button:hover{ background:var(--sfv-lime,#d2e113); color:var(--ink,#141210); }
.exam-zoomui button[disabled]{ opacity:.4; cursor:default; }

.exam-thumbs{ display:flex; gap:8px; padding:12px 18px; overflow-x:auto; }
.exam-thumbs button{
  flex:0 0 auto; width:58px; height:58px; padding:0; cursor:pointer;
  border:1px solid var(--rule-c); background:var(--stone,#f3e8d4);
  transition:border-color var(--dur) var(--ease-out);
}
.exam-thumbs button.is-on{ border-color:var(--ink,#141210); box-shadow:0 0 0 2px var(--sfv-lime,#d2e113); }
.exam-thumbs img{ width:100%; height:100%; object-fit:cover; display:block; }

.exam-text{ padding:22px 24px 30px; }
.exam-title{
  font-family:'Abril Fatface',serif; font-weight:400; line-height:1.1;
  font-size:clamp(1.5rem,3.4vw,2.1rem); margin-bottom:10px; text-wrap:balance;
}
.exam-caption{
  font-family:'Lustria',Georgia,serif; font-size:1rem; line-height:1.7;
  color:#241f1a; margin-bottom:18px; text-wrap:pretty;
}
.exam-story{
  font-family:'Lustria',Georgia,serif; font-size:1rem; line-height:1.75;
  color:#241f1a; padding-top:18px; border-top:1px solid var(--rule-c);
}
.exam-story p{ margin-bottom:14px; }

/* The metadata block is the specimen card. Provenance is not decoration:
   for a vintage object it is most of what separates it from second-hand. */
.exam-meta{ margin:20px 0 0; display:grid; grid-template-columns:auto 1fr; gap:0; }
.exam-meta dt{
  font-family:'Rosario',sans-serif; font-size:.6rem; letter-spacing:.16em;
  text-transform:uppercase; font-weight:700; color:var(--charcoal,#524b43);
  padding:9px 18px 9px 0; border-top:1px solid var(--rule-c); white-space:nowrap;
}
.exam-meta dd{
  font-family:'Rosario',sans-serif; font-size:.9rem; color:var(--ink,#141210);
  padding:9px 0; border-top:1px solid var(--rule-c);
}

.exam-actions{
  flex:0 0 auto; padding:16px 18px; border-top:1px solid var(--rule-c);
  background:var(--paper,#faf3e6); display:flex; gap:10px; flex-wrap:wrap;
  align-items:center;
}

/* ==========================================================================
   3. CABINET / DRAWER
   A container that opens. Eras, collections, categories, archive boxes.
   Built on <details> so it works with no JavaScript at all and is keyboard
   and screen-reader correct for free.
   ========================================================================== */
.cabinet{ display:grid; gap:2px; background:var(--rule-c); border:1px solid var(--rule-c); }

.drawer{ background:var(--paper,#faf3e6); }
.drawer > summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; gap:16px;
  padding:18px 22px; min-height:var(--tap,44px);
  transition:background var(--dur) var(--ease-out);
}
.drawer > summary::-webkit-details-marker{ display:none; }
.drawer > summary:hover{ background:var(--stone,#f3e8d4); }

/* The pull. A brass drawer pull, drawn rather than pictured. */
.drawer-pull{
  flex:0 0 auto; width:34px; height:14px; position:relative;
  border:1.5px solid var(--antique-gold,#7c5c1d); border-top-width:0;
  border-radius:0 0 3px 3px;
  transition:transform var(--dur-drawer) var(--ease-weight);
}
.drawer-pull::before{
  content:''; position:absolute; left:50%; top:-5px; transform:translateX(-50%);
  width:16px; height:5px; border:1.5px solid var(--antique-gold,#7c5c1d);
  border-bottom:0; border-radius:3px 3px 0 0;
}
.drawer[open] > summary .drawer-pull{ transform:translateY(3px); }

.drawer-name{
  font-family:'Abril Fatface',serif; font-weight:400; font-size:1.15rem;
  line-height:1.2; flex:1 1 auto;
}
.drawer-count{
  font-family:'Rosario',sans-serif; font-size:.62rem; letter-spacing:.18em;
  text-transform:uppercase; font-weight:700; color:var(--charcoal,#524b43);
}
.drawer-body{ padding:0 22px 24px; }

/* The slide. Height cannot be transitioned from auto, so the contents travel
   and fade while the element itself simply becomes present. Cheap, smooth,
   and it never fights the layout. */
.drawer[open] .drawer-body{ animation:drawer-out var(--dur-drawer) var(--ease-weight) both; }
@keyframes drawer-out{
  from{ opacity:0; transform:translateY(-10px); }
  to{ opacity:1; transform:none; }
}

/* ==========================================================================
   4. BOTANICAL INTERACTION LANGUAGE
   The rule is rarity. A moth that always moves is a decoration. A moth that
   moves once, when you happen to pass it, is a discovery. Nothing in here
   animates on load, nothing loops, nothing sits in a reading column.
   ========================================================================== */
.bot{
  position:absolute; pointer-events:none; user-select:none;
  opacity:.16; color:var(--antique-gold,#7c5c1d);
}
.bot svg{ display:block; width:100%; height:auto; }

/* A live specimen: reacts to a pointer passing near it, once. */
.bot-live{ pointer-events:auto; transition:opacity var(--dur-slow) var(--ease-out); }
.bot-live.is-stirred{ opacity:.34; }
.bot-live .wing{
  transform-origin:60% 50%;
  transition:transform .42s var(--ease-latch);
}
.bot-live.is-stirred .wing{ transform:rotate(-13deg) translateX(2px); }

/* A chapter marker: a pressed specimen at a section boundary. Static. */
.bot-marker{
  position:relative; display:block; width:52px; margin:0 auto;
  opacity:.3; color:var(--antique-gold,#7c5c1d);
}

/* A discovery pin: marks something hidden. Breathes only on hover, and only
   for people who have not asked for less motion. */
.bot-find{ cursor:pointer; }
.bot-find:hover{ opacity:.5; }

/* ==========================================================================
   5. REDUCED MOTION
   Not a degraded experience. A different, quieter one. Everything still
   arrives, opens, closes and can be examined. It simply does not travel.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  .artifact,
  .artifact-plate img,
  .exam, .exam-scrim, .exam-stage img,
  .drawer-pull{
    transition-duration:.01ms !important;
    animation-duration:.01ms !important;
  }
  .artifact:hover, .artifact:focus-visible, .artifact:active, .artifact.is-open{
    transform:none;
  }
  .artifact:hover .artifact-plate img{ transform:none; }
  .exam{ transform:none; opacity:0; visibility:hidden; }
  .exam.is-on{ opacity:1; visibility:visible; }
  .drawer[open] .drawer-body{ animation:none; }
  .bot-live .wing{ transition:none; }
  .bot-live.is-stirred .wing{ transform:none; }
}

/* Focus is never optional. Matches the site ring: ink for shape, lime for
   signal, because lime alone is 1.34:1 on ivory and would be invisible. */
:where(.artifact, .exam-close, .exam-zoomui button, .exam-thumbs button,
       .drawer > summary, .bot-find):focus-visible{
  outline:2px solid var(--ink,#141210); outline-offset:2px;
  box-shadow:0 0 0 4px var(--sfv-lime,#d2e113);
}

/* The page behind an overlay must not scroll under it. */
html.exam-open, body.exam-open{ overflow:hidden; }
