/* Keepsakes: crystal callouts + the examine card. Owned by layers/crystals.js.
   Ink follows var(--ink) (hud.js rewrites it per leg); hairlines are slate. */

.hud-layer > .cx {
  position: fixed;
  inset: 0;
  pointer-events: none;     /* only the buttons, labels and card take input */
  z-index: 1;
  --cx-hair: color-mix(in oklab, var(--ink, #16212b) 58%, transparent);
  --cx-ink: var(--ink, #16212b);
  --cx-soft: color-mix(in oklab, var(--ink, #16212b) 70%, transparent);
  --cx-ease: cubic-bezier(.2, .7, .1, 1);
}
/* frost.css hooks: its zero-specificity rule sets letter-spacing on every
   [data-ice] element, so the base spacing goes through --ice-ls, and the frost
   creep is re-added wherever a row sets its own spacing. Declared on the rows
   themselves so it reads each row's own --frost-l (set inline by fx/frost.js). */
.cx [data-ice] {
  --cx-creep: calc(var(--frost-l, var(--frost, 0)) * .035em);
  /* frost.css owns text-shadow on [data-ice] and appends this, so the label
     halo (set on .cx-label below) is not wiped out by the frost shadows */
  --ice-halo: 0 0 1.2em var(--halo, transparent), 0 0 .3em var(--halo, transparent);
}

/* ---------------------------------------------------------------- leaders */
.cx-lines {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
}
.cx-lead path {
  fill: none;
  stroke: var(--cx-hair);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  /* undraws fast, draws slow (pass 3: a 900 ms undraw left a stub hanging in the sky) */
  transition: stroke-dashoffset 260ms cubic-bezier(.4, 0, 1, 1);
}
.cx-lead .cx-dot {
  fill: none;
  stroke: var(--cx-ink);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(.2);
  transition: opacity 220ms var(--cx-ease), transform 220ms var(--cx-ease);
}
.cx-lead .cx-dot-c { fill: var(--cx-ink); opacity: 0; transition: opacity 220ms var(--cx-ease); }
.cx-lead.is-on path { stroke-dashoffset: 0; transition: stroke-dashoffset 900ms var(--cx-ease) 80ms; }
.cx-lead.is-on .cx-dot { opacity: .9; transform: scale(1); transition: opacity 400ms var(--cx-ease), transform 700ms var(--cx-ease); }
.cx-lead.is-on .cx-dot-c { opacity: 1; transition: opacity 400ms var(--cx-ease); }
/* the anchor breathes, like a reading being taken */
.cx-lead.is-on .cx-dot { animation: cx-ping 2.8s var(--cx-ease) 1s infinite; }
@keyframes cx-ping {
  0%, 70%, 100% { transform: scale(1); opacity: .9; }
  35% { transform: scale(1.9); opacity: .25; }
}

/* ---------------------------------------------------------------- callout */
.cx-label {
  position: absolute; left: 0; top: 0;
  font-family: var(--font-hud);
  font-size: var(--hud-size, 10.5px);
  font-weight: 400;
  letter-spacing: .08em;
  --ice-ls: .08em;
  text-transform: uppercase;
  line-height: 1.55;
  color: var(--cx-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  cursor: pointer;
  will-change: transform, opacity;
  transition: opacity 500ms var(--cx-ease), visibility 0s linear 500ms;
  text-shadow: 0 0 1.2em var(--halo, transparent), 0 0 .3em var(--halo, transparent);
  display: flex; flex-direction: column; align-items: flex-start;
}
.cx-label.is-on {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity 500ms var(--cx-ease) 260ms, visibility 0s;
}
.cx-label.is-measure { opacity: 0; visibility: hidden; transition: none; }
.cx-label[data-side="l"] { text-align: right; align-items: flex-end; }
.cx-row { margin: 0; }
.cx-row--id { font-weight: 500; letter-spacing: calc(.12em + var(--cx-creep)); }
.cx-row--soft { opacity: .74; font-weight: 300; }   /* opacity, not colour: frost owns the colour drift */
.cx-label__top { padding-bottom: .45em; }
/* hanging under the rule (the leader comes from above): rule, rows, EXAMINE */
.cx-label[data-mode="under"] .cx-label__rule { order: -1; }
.cx-label[data-mode="under"] .cx-label__top { padding: .5em 0 0; }
.cx-label[data-mode="under"] .cx-cta { padding-top: .35em; }
.cx-label__rule { height: 0; align-self: stretch; }   /* the SVG underline sits exactly here */
.cx-cta {
  margin: 0;
  padding-top: .5em;
  display: inline-flex; align-items: center; gap: .7em;
  font-weight: 500;
  letter-spacing: calc(.14em + var(--cx-creep));
}
/* EXAMINE sits at the far end of the rule, away from where the leader lands */
.cx-label[data-side="r"] .cx-cta { align-self: flex-end; flex-direction: row-reverse; }
.cx-label[data-side="l"] .cx-cta { align-self: flex-start; }
.cx-plus {
  position: relative;
  width: 11px; height: 11px;
  border: 1px solid currentColor; border-radius: 50%;
  flex: none;
  transition: transform 500ms var(--cx-ease), background-color 300ms var(--cx-ease);
}
.cx-plus::before, .cx-plus::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 5px; height: 1px; background: currentColor;
  transform: translate(-50%, -50%);
}
.cx-plus::after { transform: translate(-50%, -50%) rotate(90deg); }
.cx-cta__t { position: relative; }
.cx-cta__t::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 450ms var(--cx-ease);
}
.cx-label[data-side="r"] .cx-cta__t::after { transform-origin: right; }
.cx-label.is-hover .cx-cta__t::after { transform: scaleX(1); }
.cx-label.is-hover .cx-plus { transform: rotate(90deg); }

/* ---------------------------------------------------------------- hit areas */
.cx-hit {
  position: absolute; left: 0; top: 0;
  width: 10px; height: 10px;
  margin: 0; padding: 0; border: 0;
  background: transparent;
  border-radius: 50%;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  will-change: transform;
}
.cx-hit[hidden] { display: none; }
.cx-hit:focus { outline: none; }
.cx-hit:focus-visible {
  outline: 1px dashed var(--cx-ink);
  outline-offset: 6px;
}
.is-open .cx-hit { cursor: default; }

/* ---------------------------------------------------------------- card */
.cx-card {
  position: absolute;
  left: 55%; top: 50%;
  width: min(27rem, 36vw);
  box-sizing: border-box;
  padding: clamp(20px, 2.2vw, 30px) clamp(20px, 2.4vw, 32px) clamp(18px, 2vw, 26px);
  color: var(--cx-ink);
  background:
    linear-gradient(170deg, rgba(246, 249, 251, .62), rgba(214, 226, 235, .42));
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 2px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .5) inset,
    0 40px 80px -40px rgba(22, 33, 43, .45);
  backdrop-filter: blur(18px) saturate(1.15) brightness(1.04);
  -webkit-backdrop-filter: blur(18px) saturate(1.15) brightness(1.04);
  pointer-events: auto;
  opacity: 0;
  transform: translate3d(0, calc(-50% + 18px), 0);
  filter: blur(6px);
  transition: opacity 500ms var(--cx-ease), transform 800ms var(--cx-ease), filter 600ms var(--cx-ease);
}
.cx-card[hidden] { display: none; }
.cx-card.is-on { opacity: 1; transform: translate3d(0, -50%, 0); filter: none; transition-delay: 180ms; }
.cx-card:focus, .cx-card:focus-visible { outline: none; }  /* focus lands here for AT; Close carries the ring */

.cx-card__tick { position: absolute; width: 9px; height: 9px; border: 0 solid var(--cx-ink); }
.cx-card__tick--tl { left: -1px; top: -1px; border-left-width: 1px; border-top-width: 1px; }
.cx-card__tick--br { right: -1px; bottom: -1px; border-right-width: 1px; border-bottom-width: 1px; }

.cx-card__eyebrow {
  margin: 0 0 .9em;
  display: flex; justify-content: space-between; gap: 1em;
  font-family: var(--font-hud); font-size: var(--hud-size, 10.5px);
  letter-spacing: calc(.12em + var(--cx-creep)); text-transform: uppercase; font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.cx-card__temp { font-weight: 300; opacity: .74; }
.cx-card__title {
  margin: 0 0 .55em;
  font-family: var(--font-hud); font-size: var(--hud-size, 10.5px);
  letter-spacing: calc(.12em + var(--cx-creep)); text-transform: uppercase; font-weight: 300;
  padding-bottom: 1.1em;
  border-bottom: 1px solid var(--cx-hair);
}
.cx-card__story {
  margin: 0;
  font-family: var(--font-display);
  font-style: normal;            /* roman, never italic */
  font-weight: 400;
  font-size: clamp(1.1rem, .5vw + .85rem, 1.38rem);
  line-height: 1.26;
  letter-spacing: -.008em;
  font-variation-settings: "opsz" 28;
  text-wrap: pretty;
}
.cx-card__line {
  display: block;
  padding-left: .9em; text-indent: -.9em;   /* a wrapped line hangs, like verse */
  opacity: 0;
  transform: translateY(.45em);
  clip-path: inset(0 0 100% 0);
}
.cx-card.is-on .cx-card__line {
  opacity: 1; transform: none; clip-path: inset(0 0 -10% 0);
  transition: opacity 700ms var(--cx-ease), transform 900ms var(--cx-ease), clip-path 900ms var(--cx-ease);
  transition-delay: calc(360ms + var(--i, 0) * 140ms);
}
.cx-card__line + .cx-card__line { margin-top: .12em; }
.cx-card__foot {
  margin-top: 1.4em;
  display: flex; align-items: center; justify-content: space-between; gap: 1em;
  font-family: var(--font-hud); font-size: calc(var(--hud-size, 10.5px) * .95);
  letter-spacing: .1em; text-transform: uppercase;
}
.cx-card__meta { margin: 0; font-weight: 300; opacity: .74; font-variant-numeric: tabular-nums; letter-spacing: calc(.1em + var(--cx-creep)); }
.cx-card__close {
  appearance: none; border: 0; background: none;
  margin: -.6em -.4em; padding: .6em .4em;
  font: inherit; letter-spacing: calc(.1em + var(--cx-creep)); text-transform: inherit;
  font-weight: 500;
  display: inline-flex; align-items: center; gap: .6em;
  cursor: pointer;
}
.cx-card__close i { position: relative; width: 9px; height: 9px; }
.cx-card__close i::before, .cx-card__close i::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 11px; height: 1px;
  background: currentColor; transform: translate(-50%, -50%) rotate(45deg);
  transition: transform 400ms var(--cx-ease);
}
.cx-card__close i::after { transform: translate(-50%, -50%) rotate(-45deg); }
.cx-card__close:hover i::before { transform: translate(-50%, -50%) rotate(135deg); }
.cx-card__close:hover i::after { transform: translate(-50%, -50%) rotate(45deg); }
.cx-card__close:focus { outline: none; }
.cx-card__close:focus-visible { outline: 1px solid var(--cx-ink); outline-offset: 3px; border-radius: 2px; }

/* While an artifact is examined it fills the frame: the page copy steps aside.
   filter, not opacity, so it composes with the engine's own copy fades. */
.copy { transition: filter 600ms cubic-bezier(.2, .7, .1, 1); }
.is-examining .copy { filter: opacity(0); }

/* portrait: the block rises to the top half, the card sits low */
@media (max-aspect-ratio: 1/1) {
  .cx-card {
    left: var(--gut, 16px); right: var(--gut, 16px); top: auto;
    bottom: calc(var(--gut, 16px) + 58px);
    width: auto;
    transform: translate3d(0, 18px, 0);
  }
  .cx-card.is-on { transform: none; }
  .cx-card__story { font-size: clamp(1.05rem, 4.4vw, 1.25rem); }
}

@media (prefers-reduced-motion: reduce) {
  .cx-card, .cx-card__line, .cx-label, .cx-lead path { transition: none !important; }
  .cx-lead.is-on .cx-dot { animation: none; }
}
