/* Oriel — space.css
   Where the physics lands (the 18 Laws, the structural half): the room's depth, which surfaces float and how high,
   the controls, the thinking channel, and how the Desk hangs on each screen. It changes no colour, paper or face;
   the materials and textures come next, into the slots the kit leaves for them (the --m-* tokens, Matter.paint).
   Loaded after styles.css and matter.css, on Oriel's pages and the warriors'. */

/* ---------------------------------------------------------------- depth (Laws 2, 11)
   The room is layered: the sky and its stars deepest, the bamboo in the middle, the chamber's floor, then the
   surfaces you touch. As the light moves (the phone tilting) each layer slides by its depth, the far ones furthest,
   and the near surfaces a little the other way. Position only: the compositor moves them, nothing repaints. */
.stars { translate: calc(var(--light-x) * 10px) calc(var(--light-y) * 10px); scale: 1.06; will-change: translate; }
.eclipse { translate: calc(var(--light-x) * 12px) calc(var(--light-y) * 9px); }
.bamboo { translate: calc(var(--light-x) * 5px) calc(var(--light-y) * 4px); scale: 1.035; will-change: translate; }
.horizon, .sky { translate: calc(var(--light-x) * 7px) calc(var(--light-y) * 3px); }
.home .mark-wrap { translate: calc(var(--light-x) * -3px) calc(var(--light-y) * -3px); }
/* the near surfaces shift by their height (Gemini's sub-millimetre parallax): a higher card moves more */
.wcard, .tile, .silk { translate: calc(var(--light-x) * var(--z, 8) * -.16px) calc(var(--light-y) * var(--z, 8) * -.16px); }

/* the orb's glass (230% of its mark) reached past a 320px screen and let the page pan sideways; a screen clips its
   sides now (clip, not hidden: no scroll container, so sticky bars still stick). v67 */
.screen { overflow-x: clip; }

/* ---------------------------------------------------------------- floating surfaces (Law 2)
   Each floating surface keeps its own hairline and takes the kit's lift: the lit edge, the bevel, a tight grounding
   shadow and an umbra thrown from the light. Heights are Gemini's tiers (v66 addendum): the chamber floor 0, a
   recessed well -3, standard Desk cards 8 (Studio plays, Abilities), hero monoliths 14 (the warriors, the Brief
   slab), the Desk's tab bar 20 riding above them all; a source 7, a settings group 6, an open sheet 20. Pressed, a
   slab sinks to 4. */
html .wcard { --z: 14; box-shadow: var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html .wcard:active { --z: 4; }
html .tile { --z: 8; box-shadow: inset 0 0 0 var(--hair) var(--line), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html .tile.hero { --z: 14; box-shadow: inset 0 0 0 var(--hair) var(--line-2), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html .tile:active { --z: 4; box-shadow: inset 0 0 0 var(--hair) var(--line-2), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html .folio { --z: 7; box-shadow: inset 0 0 0 var(--hair) rgba(240, 226, 206, .2), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html .folio:active { --z: 2; }
html .group, html .card { --z: 6; box-shadow: inset 0 0 0 var(--hair) var(--line), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html .group.able, html .group.skills { --z: 8; }
html .group.inset { --z: 0; box-shadow: inset 0 0 0 var(--hair) var(--line), inset 0 1px 3px rgba(var(--m-shadow), .45); } /* a well, sunk into the page */
html .sheet { --z: 20; box-shadow: inset 0 0 0 var(--hair) var(--line-2), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html .silk { --z: 14; box-shadow: var(--lev-ground), var(--lev-cast); }
html .silk:active { --z: 4; }

html[data-theme="light"] .wcard { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .1), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .tile, html[data-theme="light"] .tile.hero { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .1), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .tile:active { box-shadow: inset 0 0 0 var(--hair) rgba(163, 88, 47, .45), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .folio { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .1), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .group, html[data-theme="light"] .card { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .09), var(--lev-rim), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .group.inset { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .09), inset 0 1px 3px rgba(var(--m-shadow), .14); }
html[data-theme="light"] .sheet { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .1), var(--lev-rim), var(--lev-base), var(--lev-ground), var(--lev-cast); }

/* a warrior's skills read as one quiet line of marks: an older rule boxed each one in a hairline (v65), which Fable's
   own rule meant to remove; light mode already had it off */
html .wcaps span { box-shadow: none; }

/* ---------------------------------------------------------------- the detent switch (Law 6)
   A ceramic block in a machined groove. It slides with weight, then drops into the detent at the far end (a fraction
   of a pixel, felt more than seen). The empty detent is marked by a fine tick; the groove takes her copper when on.
   It doesn't stretch under the finger: ceramic doesn't. */
.switch {
  width: 50px; height: 28px; border-radius: 8px; background: var(--m-groove);
  box-shadow: inset 0 1px 2.5px rgba(var(--m-shadow), .6), inset 0 0 0 .5px rgba(var(--m-shadow), .3), inset 0 -1px 0 var(--m-rim-light);
  transition: background .5s var(--spring-heavy);
}
.switch::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: .8;
  background: linear-gradient(var(--m-mark), var(--m-mark)) 13.5px 50% / .5px 9px no-repeat, linear-gradient(var(--m-mark), var(--m-mark)) calc(100% - 13.5px) 50% / .5px 9px no-repeat;
}
.switch i {
  z-index: 1; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 6px; background: var(--m-block);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), inset 0 -1px 0 rgba(var(--m-shadow), .16), 0 1.5px 2px rgba(var(--m-shadow), .5), calc(var(--light-x) * -1.5px) calc(3px - var(--light-y) * 1px) 6px rgba(var(--m-shadow), .3);
  transition: transform var(--t-move) var(--spring-heavy); animation: detent-a .62s both;
}
.switch.on { /* her copper fills the groove when on */ background: rgba(var(--m-copper), .4); box-shadow: inset 0 1px 2.5px rgba(var(--m-shadow), .5), inset 0 0 0 .5px rgba(var(--m-copper), .6), inset 0 -1px 0 var(--m-rim-light); }
.switch.on i { transform: translateX(22px); background: var(--m-block); animation-name: detent-b; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), inset 0 -1px 0 rgba(var(--m-shadow), .16), 0 1.5px 2px rgba(var(--m-shadow), .5), calc(var(--light-x) * -1.5px) calc(3px - var(--light-y) * 1px) 6px rgba(var(--m-shadow), .3); }
button.row:active .switch i { width: 22px; }
button.row:active .switch.on i { transform: translateX(22px); }
@keyframes detent-a { 0%, 72% { translate: 0 0; } 84% { translate: 0 .8px; } 100% { translate: 0 0; } }
@keyframes detent-b { 0%, 72% { translate: 0 0; } 84% { translate: 0 .8px; } 100% { translate: 0 0; } }

/* ---------------------------------------------------------------- the thinking channel (Law 10)
   The pearl, then what she's doing in plain words, and under it the groove, running only while she produces. */
.think { display: inline-grid; grid-template-columns: auto minmax(0, auto); column-gap: 10px; row-gap: 6px; align-items: center; }
.think > .liquid, .think > .think-mark { grid-row: 1 / span 2; }
.think > .thinking { grid-column: 2; grid-row: 1; }
.think > .groove { grid-column: 2; grid-row: 2; }

/* ---------------------------------------------------------------- the Desk's tab bar rides highest (z 20)
   It floats over the warriors as the page scrolls under it, its shadow following the light. Its thumb now glides
   with the room's heavy motion: the old curve overshot, and Law 4 is no bounce. */
html .dseg { --z: 20; box-shadow: inset 0 0 0 var(--hair) var(--line-2), inset 0 1px 0 rgba(255, 255, 255, .07), inset 0 -1px 0 rgba(0, 0, 0, .35), var(--lev-ground), var(--lev-cast); }
html[data-theme="light"] .dseg { box-shadow: inset 0 0 0 var(--hair) rgba(40, 30, 22, .1), inset 0 1px 0 #fff, var(--lev-ground), var(--lev-cast); }
.dseg-thumb { transition: transform .6s var(--spring-heavy); }

/* ---------------------------------------------------------------- the warrior's status, a recessed well (z -3)
   Its line sits in a well cut into the card: a darker floor, the shade inside the lip on the side the light comes
   from, a catch of light on the far lip. The light moves it. (Gemini's cutout well, v66.) */
.wstat {
  margin-top: 16px; padding: 9px 12px; border-radius: 10px; background: rgba(0, 0, 0, .3);
  box-shadow: inset calc(var(--light-x) * -2px + 0px) calc(var(--light-y) * -2px + 1.5px) 5px rgba(var(--m-shadow), var(--m-ao-a)), inset 0 -1px 0 var(--m-rim-light), inset 0 0 0 .5px rgba(0, 0, 0, .35);
}
html[data-theme="light"] .wstat { background: rgba(60, 40, 22, .045); background-image: none; box-shadow: inset calc(var(--light-x) * -2px) calc(var(--light-y) * -2px + 1.5px) 4px rgba(var(--m-shadow), .16), inset 0 -1px 0 var(--m-rim-light), inset 0 0 0 .5px rgba(60, 40, 22, .08); }
html .wstat { background-image: none; }
@media (min-width: 720px) { .wstat { position: static; } }

/* ---------------------------------------------------------------- the coordinate stamp and registration mark
   Each warrior card carries its height and its number in the corner, the way machined parts are marked
   ("Z+14.0 // 01"), beside a fine registration cross. Set from the card's real height (app.js). */
.wstamp { position: absolute; z-index: 2; top: 8px; right: 14px; display: inline-flex; align-items: center; gap: 6px; pointer-events: none;
  font-family: var(--f-mark); font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--m-mark); opacity: .8; white-space: nowrap; }
.wstamp::after { content: ""; width: 7px; height: 7px; flex: none;
  background: linear-gradient(var(--m-mark), var(--m-mark)) center / 7px .5px no-repeat, linear-gradient(var(--m-mark), var(--m-mark)) center / .5px 7px no-repeat; }

/* ---------------------------------------------------------------- light lying across the surfaces (Law 7)
   A soft sheen on the side of each card facing the light; it turns as the phone tilts (--light-deg). */
.wcard::after, .tile::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: linear-gradient(var(--light-deg), rgba(var(--m-sheen), var(--m-sheen-a)), rgba(var(--m-sheen), 0) 58%);
}

/* ---------------------------------------------------------------- the Tilt control, in the Desk header's empty corner
   A small well with a jewel of ice-water light that rides with the light; copper rim when the tilt is live. One tap
   asks the phone for its motion, or turns the tilt off. (Gemini's Desk tilt pill, v66, as a mark instead of a label.) */
.tiltpip { width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%; -webkit-tap-highlight-color: transparent; }
.tiltpip i { position: relative; display: block; width: 20px; height: 20px; border-radius: 50%; background: var(--m-groove);
  box-shadow: inset 0 1px 2px rgba(var(--m-shadow), .55), inset 0 -.5px 0 var(--m-rim-light), 0 0 0 .75px var(--m-mark); transition: box-shadow .5s var(--spring-heavy); }
.tiltpip i::after { content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: var(--m-mark);
  translate: calc(var(--light-x) * 4px) calc(var(--light-y) * 4px); transition: background .4s var(--spring-heavy); }
.tiltpip[aria-checked="true"] i { box-shadow: inset 0 1px 2px rgba(var(--m-shadow), .55), inset 0 -.5px 0 var(--m-rim-light), 0 0 0 1px rgba(var(--m-copper), .9); }
.tiltpip[aria-checked="true"] i::after { background: rgb(var(--m-ice)); box-shadow: 0 0 5px rgba(var(--m-ice), .7); }
.tiltpip:active i { scale: .92; }

/* ---------------------------------------------------------------- the metallic grey shimmer (Gemini's note)
   Never a rainbow or a neon pulse: one slow band of liquid mercury sweeps through the thinking groove each time her
   step changes, then the groove is still metal again. */
.groove::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(110deg, transparent 35%, rgba(200, 206, 216, .5) 50%, transparent 65%) 180% 0 / 220% 100% no-repeat; }
.groove.sweep::after { animation: mercury 1.4s var(--spring-heavy) both; }
@keyframes mercury { 0% { opacity: 1; background-position: 180% 0; } 85% { opacity: 1; } 100% { opacity: 0; background-position: -40% 0; } }


/* ---------------------------------------------------------------- the Atelier's layout choice */
#layoutRow, #paperRow, #typeRow { grid-template-columns: minmax(0, 1fr); gap: 11px; }
/* her horological symbols over the Desk's tab labels, and her monogram at the foot of the Atelier (house type only) */
.dsym { display: none; }
html[data-type="house"] .dsym { display: block; height: 15px; margin: 0 auto 3px; }
html[data-type="house"] .dsym svg { width: 15px; height: 15px; display: block; margin: 0 auto; }
html[data-type="house"] .dseg button { padding-top: 7px; padding-bottom: 7px; }
.foundry-mark { display: none; }
html[data-type="house"] .foundry-mark { display: block; margin: 26px auto 4px; height: 15px; color: var(--m-mark); text-align: center; }
html[data-type="house"] .foundry-mark svg { height: 15px; width: auto; }
.wstamp .oriel-carved-svg { height: 12px; width: auto; margin-top: -1px; }
#layoutRow .opts { --n: 3; }

/* ---------------------------------------------------------------- the Desk, hung two new ways (Law 8, mockups)
   Column is the Desk as it was. Gallery: one heavy anchor surface (the first warrior) with the others held off its
   edge, overlapping it like pieces hung on a gallery wall. Offset: one column, each card pushed off-centre in turn,
   its detail stepping into the margin on the open side. Chosen in the Atelier; only the Warriors tab changes. */

/* Gallery on the phone: the anchor rides low and tall; the others hang off the one above, alternately off-centre */
@media (max-width: 719px) {
  html[data-layout="gallery"] .roster { gap: 0; }
  html[data-layout="gallery"] .roster .wcard:first-child { --z: 8; padding: 22px 18px 34px 22px; grid-template-columns: 84px minmax(0, 1fr) 18px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wemb { width: 84px; height: 84px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wspot { scale: 1.2; }
  html[data-layout="gallery"] .roster .wcard:first-child .wname { font-size: 34px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wjob { font-size: 19.5px; }
  html[data-layout="gallery"] .roster .wcard:nth-child(n+2) { --z: 18; margin-top: -14px; }
  html[data-layout="gallery"] .roster .wcard:not(:last-child) { padding-bottom: 30px; }
  html[data-layout="gallery"] .roster .wcard:nth-child(2) { z-index: 2; margin-left: 10px; margin-right: -8px; }
  html[data-layout="gallery"] .roster .wcard:nth-child(3) { z-index: 3; margin-left: -8px; margin-right: 10px; }
  html[data-layout="gallery"] .roster .wcard:nth-child(4) { z-index: 4; margin-left: 10px; margin-right: -8px; }
  html[data-layout="offset"] .roster { gap: 18px; }
  html[data-layout="offset"] .roster .wcard:nth-child(odd) { margin-left: -8px; margin-right: 12px; }
  html[data-layout="offset"] .roster .wcard:nth-child(even) { margin-left: 12px; margin-right: -8px; }
}

/* Gallery on the iPad: the Desk opens to the room. The anchor holds the left; the other three hang off its right edge,
   stepped, riding higher. The tabs stay a hand's width. */
@media (min-width: 720px) {
  html[data-layout="gallery"] #s-desk { max-width: min(1000px, 92vw); }
  html[data-layout="gallery"] #s-desk .dseg { max-width: 460px; margin-left: auto; margin-right: auto; }
  html[data-layout="gallery"] #s-desk .dlede { max-width: 460px; }
  html[data-layout="gallery"] #dpane-studio, html[data-layout="gallery"] #dpane-abilities, html[data-layout="gallery"] #dpane-computer { width: 100%; max-width: 460px; margin-left: auto; margin-right: auto; }
  html[data-layout="gallery"] .roster { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 20px 0; align-items: start; padding: 6px 0 48px; }
  html[data-layout="gallery"] .roster .wcard:first-child {
    --z: 9; grid-column: 1 / 8; grid-row: 1 / span 3; align-self: stretch; z-index: 1; align-content: start;
    grid-template-columns: 128px minmax(0, 1fr) 18px; grid-template-rows: auto 1fr auto auto; padding: 34px 120px 34px 34px;
  }
  html[data-layout="gallery"] .roster .wcard:first-child .wjob { align-self: start; }
  html[data-layout="gallery"] .roster .wcard:first-child .being { overflow: visible; } /* the larger glow fades on its own, unclipped */
  html[data-layout="gallery"] .roster .wcard:first-child .wemb { width: 128px; height: 128px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wspot { scale: 1.65; }
  html[data-layout="gallery"] .roster .wcard:first-child .wname { font-size: 46px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wrole { font-size: 11.5px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wjob { margin-top: 30px; font-size: 24px; line-height: 1.32; max-width: 22ch; }
  html[data-layout="gallery"] .roster .wcard:first-child .wstat { margin-top: 26px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wwhen { position: static; margin-left: auto; font-size: 10.5px; }
  html[data-layout="gallery"] .roster .wcard:first-child .wwhen::before { display: none; }
  html[data-layout="gallery"] .roster .wcard:nth-child(n+2) { --z: 22; grid-column: 7 / 13; z-index: 2; }
  html[data-layout="gallery"] .roster .wcard:nth-child(2) { grid-row: 1; margin-top: 40px; }
  html[data-layout="gallery"] .roster .wcard:nth-child(3) { grid-row: 2; margin-left: 34px; z-index: 3; }
  html[data-layout="gallery"] .roster .wcard:nth-child(4) { grid-row: 3; margin-left: -18px; margin-right: 26px; z-index: 4; }
  /* their detail steps up into the gap above them, on a short leader */
  html[data-layout="gallery"] .roster .wcard:nth-child(n+2) .wwhen { left: 22px; top: auto; bottom: calc(100% + 7px); }
  html[data-layout="gallery"] .roster .wcard:nth-child(n+2) .wwhen:not(:empty)::before { top: calc(100% + 1px); right: auto; left: -8px; width: 5px; height: 5px; background: none; border-left: .5px solid var(--m-mark); border-bottom: .5px solid var(--m-mark); }

  /* Offset on the iPad: one column, the cards stepping out to either side; each card's detail sits in the margin on
     its open side */
  html[data-layout="offset"] .roster { gap: 26px; padding-bottom: 40px; }
  html[data-layout="offset"] .roster .wcard:nth-child(odd) { margin-left: -84px; margin-right: 84px; }
  html[data-layout="offset"] .roster .wcard:nth-child(even) { margin-left: 84px; margin-right: -84px; }
  html[data-layout="offset"] .roster .wcard:nth-child(even) .wwhen { left: auto; right: calc(100% + 14px); }
  html[data-layout="offset"] .roster .wcard:nth-child(even) .wwhen:not(:empty)::before { right: auto; left: calc(100% + 3px); }
}

@media (prefers-reduced-motion: reduce) {
  .stars, .eclipse, .bamboo, .horizon, .sky, .home .mark-wrap, .wcard, .tile, .silk, .tiltpip i::after { translate: none; }
  .switch i { animation: none; transition: none; }
  .groove.sweep::after { animation: none; }
}

/* ---------------------------------------------------------------- the warriors as medallions (v69, warrior/medallion.js)
   A recessed dial in the paper's well, a machined bezel that catches the light, the seal engraved in the paper's ink
   and the warrior's own light. Only transforms and opacity move: the motes orbit, the butterfly breathes, the ensō
   turns, the pearl falls into its rings; at work they quicken, asleep they rest. */
.medal { position: relative; display: block; width: 64px; height: 64px; color: var(--ink); --m-acc: rgb(var(--w-glow)); -webkit-tap-highlight-color: transparent; }
.medal.inline { position: absolute; left: 50%; top: 50%; width: 66px; height: 66px; margin: -33px 0 0 -33px; }
.being-spot .medal, .medal:not(.inline):not(.perched) { position: absolute; left: 50%; top: 50%; width: 118px; height: 118px; margin: -59px 0 0 -59px; }
.medal.perched { position: absolute; left: 12px; top: -46px; width: 40px; height: 40px; margin: 0; z-index: 7; }
.medal .m-dial { position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle at 42% 36%, var(--m-surface, rgba(255, 255, 255, .06)), var(--m-well, rgba(0, 0, 0, .35)) 78%);
  box-shadow: inset calc(var(--light-x) * -2px + 0px) calc(var(--light-y) * -2px + 2px) 6px rgba(var(--m-shadow), var(--m-ao-a)), inset 0 -1px 0 var(--m-rim-light), inset 0 0 0 .5px rgba(0, 0, 0, .3); }
.medal .m-bezel { position: absolute; inset: -2px; border-radius: 50%; padding: 1.5px; pointer-events: none;
  background: conic-gradient(from calc(var(--light-deg) + 158deg), rgba(var(--m-metal), .35) 0deg, rgba(var(--m-metal), .95) 22deg, rgba(var(--m-metal), .35) 50deg, rgba(var(--m-metal), .2) 180deg, rgba(var(--m-metal), .5) 202deg, rgba(var(--m-metal), .2) 230deg, rgba(var(--m-metal), .35) 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude; }
.medal .m-seal { position: absolute; inset: 8%; width: 84%; height: 84%; overflow: visible; filter: drop-shadow(0 .5px 0 var(--m-rim-light)); }
.medal .m-glint { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; opacity: 0; background: linear-gradient(110deg, transparent 38%, rgba(var(--m-glint), .55) 50%, transparent 62%) 180% 0 / 220% 100% no-repeat; }
/* the motion */
.medal .m-orbit { transform-origin: 50px 50px; animation: m-orbit 14s linear infinite; }
.medal .m-wing.l { animation: m-wing-l 2.6s ease-in-out infinite; }
.medal .m-wing.r { animation: m-wing-r 2.6s ease-in-out infinite; }
.medal .m-enso { animation: m-turn 28s linear infinite; }
.medal .m-pearl { animation: m-fall 3.2s ease-in infinite; }
.medal .m-rip2 { animation: m-ripple 3.2s ease-out infinite; }
.medal .m-ring { transform-origin: 50px 50px; animation: m-turn 40s linear infinite; }
.medal[data-mood="think"] .m-orbit, .medal[data-mood="search"] .m-orbit, .medal[data-mood="check"] .m-orbit, .medal[data-mood="talk"] .m-orbit { animation-duration: 4s; }
.medal[data-mood="think"] .m-wing.l, .medal[data-mood="search"] .m-wing.l, .medal[data-mood="check"] .m-wing.l, .medal[data-mood="talk"] .m-wing.l,
.medal[data-mood="think"] .m-wing.r, .medal[data-mood="search"] .m-wing.r, .medal[data-mood="check"] .m-wing.r, .medal[data-mood="talk"] .m-wing.r { animation-duration: .9s; }
.medal[data-mood="think"] .m-enso, .medal[data-mood="search"] .m-enso, .medal[data-mood="check"] .m-enso, .medal[data-mood="talk"] .m-enso { animation-duration: 6s; }
.medal[data-mood="think"] .m-pearl, .medal[data-mood="search"] .m-pearl, .medal[data-mood="check"] .m-pearl, .medal[data-mood="talk"] .m-pearl,
.medal[data-mood="think"] .m-rip2, .medal[data-mood="search"] .m-rip2, .medal[data-mood="check"] .m-rip2, .medal[data-mood="talk"] .m-rip2 { animation-duration: 1.3s; }
.medal[data-mood="think"] .m-ring, .medal[data-mood="search"] .m-ring, .medal[data-mood="check"] .m-ring { animation-duration: 9s; }
.medal[data-mood="listen"] .m-seal { transform: scale(1.04); }
.medal[data-mood="sleep"] { opacity: .62; }
.medal[data-mood="sleep"] .m-orbit, .medal[data-mood="sleep"] .m-wing, .medal[data-mood="sleep"] .m-enso, .medal[data-mood="sleep"] .m-pearl, .medal[data-mood="sleep"] .m-rip2, .medal[data-mood="sleep"] .m-ring { animation-play-state: paused; }
.medal[data-mood="done"] .m-glint, .medal[data-mood="tap"] .m-glint { animation: m-glint 1.1s var(--spring-heavy) both; }
.medal[data-mood="done"] .m-seal, .medal.burst .m-seal { animation: m-pop .7s var(--spring-heavy) both; }
.medal[data-mood="error"] { --m-acc: rgb(224, 92, 110); }
.medal.pulse .m-dial { animation: m-pulse .5s ease-out both; }
.medal .m-seal { transition: transform .5s var(--spring-heavy); }
@keyframes m-orbit { to { transform: rotate(360deg); } }
@keyframes m-turn { to { transform: rotate(360deg); } }
@keyframes m-wing-l { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(.45) translateX(2px); } }
@keyframes m-wing-r { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(.45) translateX(-2px); } }
@keyframes m-fall { 0% { transform: translateY(-6px); opacity: 0; } 30% { opacity: 1; } 70% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(2px); opacity: 0; } }
@keyframes m-ripple { 0%, 60% { transform: scale(.55); opacity: 0; } 72% { opacity: .9; } 100% { transform: scale(1.25); opacity: 0; } }
@keyframes m-glint { 0% { opacity: 1; background-position: 180% 0; } 85% { opacity: 1; } 100% { opacity: 0; background-position: -40% 0; } }
@keyframes m-pop { 0% { transform: scale(1); } 35% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes m-pulse { 0% { box-shadow: inset 0 0 0 .5px rgba(0, 0, 0, .3), 0 0 0 0 rgba(var(--w-glow), .5); } 100% { box-shadow: inset 0 0 0 .5px rgba(0, 0, 0, .3), 0 0 0 10px rgba(var(--w-glow), 0); } }
/* the Desk card's emblem and the page's spots give the medallion its room; the old glow behind a figure is gone */
.wemb { background: none; }
.wemb .wspot { width: 72px; height: 72px; margin: -36px 0 0 -36px; }
.being-spot { position: relative; }
@media (prefers-reduced-motion: reduce) { .medal * { animation: none !important; } }

/* the floor the paper spiders walk (medallion.js, v72): a strip above the bar, under everything that matters */
.m-floor { position: fixed; left: 0; right: 0; height: 44px; z-index: 6; pointer-events: none; display: block; }
.tucked .m-floor { opacity: 0; }

/* the seals' own motion (v72): the fan opens a little and closes, the blade breathes, his air turns */
.medal .m-fan { animation: m-fan 7s ease-in-out infinite; }
.medal .m-air { animation: m-air 5s ease-in-out infinite; }
.medal .m-blade { animation: m-breathe 6s ease-in-out infinite; }
.medal[data-mood="think"] .m-fan, .medal[data-mood="search"] .m-fan, .medal[data-mood="check"] .m-fan, .medal[data-mood="talk"] .m-fan { animation-duration: 2.2s; }
.medal[data-mood="think"] .m-air, .medal[data-mood="search"] .m-air, .medal[data-mood="check"] .m-air, .medal[data-mood="talk"] .m-air { animation-duration: 1.4s; }
.medal[data-mood="sleep"] .m-fan, .medal[data-mood="sleep"] .m-air, .medal[data-mood="sleep"] .m-blade { animation-play-state: paused; }
@keyframes m-fan { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes m-air { 0%, 100% { transform: rotate(-6deg) scale(1); opacity: .85; } 50% { transform: rotate(6deg) scale(1.06); opacity: 1; } }
@keyframes m-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.025); } }
.medal .m-seal { inset: 4%; width: 92%; height: 92%; }

/* the figures' motion (v72): hood tails and hair ride the air, the fan turns a little, the sphere of air spins */
.medal .m-tails { animation: m-tails 4.5s ease-in-out infinite; }
.medal .m-hair { animation: m-tails 5.5s ease-in-out infinite; }
.medal[data-mood="sleep"] .m-tails, .medal[data-mood="sleep"] .m-hair { animation-play-state: paused; }
@keyframes m-tails { 0%, 100% { transform: rotate(-3deg) translateX(0); } 50% { transform: rotate(3deg) translateX(-1.5px); } }
.medal .m-air { animation: m-spin 6s linear infinite; }
@keyframes m-spin { to { transform: rotate(360deg); } }

/* the cameo (v72): a dark figure cut in the paper's deepest ink, rim-lit in its metal, on a brushed plate of that
   metal; by day the plate is the paper's lit surface and the figure its ink */
.medal { --fig: #0B0908; --fig-hi: #2A2420; }
.medal .m-dial { background: radial-gradient(circle at 38% 30%, rgba(var(--m-metal), .5), rgba(var(--m-metal), .2) 52%, rgba(var(--m-metal), .1) 100%), var(--m-surface, #1A1512);
  box-shadow: inset calc(var(--light-x) * -2px) calc(var(--light-y) * -2px + 2px) 6px rgba(var(--m-shadow), .5), inset 0 -1px 0 var(--m-rim-light), inset 0 0 0 .5px rgba(0, 0, 0, .35); }
html[data-theme="light"] .medal { --fig: var(--ink); --fig-hi: var(--ink-2); }
html[data-theme="light"] .medal .m-dial { background: radial-gradient(circle at 38% 30%, #fff, rgba(255, 255, 255, .3) 55%, rgba(var(--m-metal), .12) 100%), var(--m-surface-hi, #FFFDF9); }

/* ---------------------------------------------------------------- her thinking, as water ink (v75, both pages)
   One drop of rich ink in the paper's pigment (a warrior's light on its page): pooled and translucent at its heart,
   the pigment gathered darker at its rim the way wet ink dries, a swirl of denser ink turning inside it, a wet
   sheen, and every few seconds a bloom of it spreading into the paper and fading. It breathes, and its edge is
   never a perfect circle. The word beside it in the same ink. No pearl, no tape, no metal sheen. Transforms and
   opacity only. liquid.js puts the three layers inside the mark. */
.liquid, .liquid.lit, .liquid.inkdot { position: relative; display: inline-block; width: 24px; height: 24px; flex: none; overflow: visible;
  --tk: var(--think-ink, rgb(var(--m-pigment)));
  border-radius: 52% 48% 50% 50% / 48% 52% 48% 52%;
  background: radial-gradient(circle at 50% 52%, color-mix(in srgb, var(--tk) 34%, transparent) 0%, color-mix(in srgb, var(--tk) 60%, transparent) 46%, color-mix(in srgb, var(--tk) 92%, transparent) 76%, color-mix(in srgb, var(--tk) 72%, #000) 92%, color-mix(in srgb, var(--tk) 45%, transparent) 100%);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--tk) 12%, transparent), 0 0 12px 4px color-mix(in srgb, var(--tk) 16%, transparent);
  animation: inkbreathe 3.2s ease-in-out infinite; }
.liquid canvas { display: none !important; }
.liquid .ink-swirl { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; }
.liquid .ink-swirl::before { content: ""; position: absolute; inset: -34%; opacity: .85; will-change: transform;
  background: conic-gradient(from 0deg, transparent 0deg 40deg, color-mix(in srgb, var(--tk) 65%, #000) 95deg, transparent 150deg, color-mix(in srgb, var(--tk) 40%, #fff) 215deg, transparent 280deg, color-mix(in srgb, var(--tk) 70%, #000) 330deg, transparent 360deg);
  animation: inkswirl 5.5s linear infinite; }
.liquid .ink-sheen { position: absolute; inset: 0; border-radius: inherit; background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .42), rgba(255, 255, 255, .08) 30%, rgba(255, 255, 255, 0) 52%); animation: inksheen 5.5s ease-in-out infinite; }
.liquid .ink-bloom { position: absolute; inset: -2px; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--tk) 70%, transparent); opacity: 0; animation: inkbloom 2.8s ease-out infinite; }
@keyframes inkswirl { to { transform: rotate(360deg); } }
@keyframes inksheen { 0%, 100% { transform: translate(0, 0); opacity: .9; } 50% { transform: translate(1.5px, 1px); opacity: .6; } }
@keyframes inkbloom { 0% { transform: scale(.55); opacity: .75; } 70% { opacity: .12; } 100% { transform: scale(1.75); opacity: 0; } }
@keyframes inkbreathe { 0%, 100% { transform: scale(.95); border-radius: 52% 48% 50% 50% / 48% 52% 48% 52%; } 50% { transform: scale(1.05); border-radius: 46% 54% 49% 51% / 53% 47% 53% 47%; } }
.think .thinking, .thinking, .thinking.new { background: none !important; -webkit-background-clip: initial !important; background-clip: initial !important; -webkit-text-fill-color: currentColor !important; color: var(--think-ink, rgb(var(--m-pigment))) !important; animation: inkword 3.2s ease-in-out infinite !important; font-family: var(--f-mark, var(--mono)); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
@keyframes inkword { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }
.think > .groove, .groove { display: none !important; }
.think { column-gap: 10px; row-gap: 0; }
/* the speak button in the chat's bar (v75): a drop of ink, and rings of it spreading while she reads aloud */
#s-chat .icon.wave svg { display: none; }
#s-chat .icon.wave { position: relative; }
#s-chat .icon.wave::before { content: ""; position: absolute; left: 50%; top: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 52% 48% 50% 50% / 48% 52% 48% 52%;
  background: radial-gradient(circle at 40% 36%, color-mix(in srgb, rgb(var(--m-pigment)) 70%, #fff), rgb(var(--m-pigment)) 55%, color-mix(in srgb, rgb(var(--m-pigment)) 70%, #000)); opacity: .55; transition: opacity .4s var(--spring-heavy); }
#s-chat .icon.wave[aria-pressed="true"]::before { opacity: 1; }
#s-chat .icon.wave::after { content: ""; position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; border: 1.2px solid rgba(var(--m-pigment), .55); opacity: 0; transition: opacity .4s var(--spring-heavy); }
#s-chat .icon.wave[aria-pressed="true"]::after { opacity: .6; }
#s-chat .icon.wave.speaking::after { animation: speakring 1.5s ease-out infinite; }
@keyframes speakring { 0% { transform: scale(.5); opacity: .9; } 100% { transform: scale(1.5); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .liquid, .liquid .ink-swirl::before, .liquid .ink-sheen, .liquid .ink-bloom, .thinking, #s-chat .icon.wave::after { animation: none !important; } }

/* ---------------------------------------------------------------- the ink angels (v77, warrior/angels.js)
   On the Desk the angel spills a little past its emblem (its wings want the room); on a warrior's page it fills its
   spot, and at work it perches on the bar. */
.being.angel { position: absolute; inset: 0; left: 0; top: 0; width: 100%; height: 100%; transform: none; will-change: auto; z-index: 1; }
.being.angel .being-canvas { position: absolute; inset: 0; }
.being.angel.perched { inset: auto; left: 6px; top: -74px; width: 76px; height: 76px; z-index: 7; }
.wemb .wspot { width: 96px; height: 96px; margin: -48px 0 0 -48px; }

/* ---------------------------------------------------------------- an angel that can't show says why (v78)
   Small type at the foot of its card, only when something went wrong; a screenshot carries the reason. */
.wcard .wink { position: absolute; left: 16px; right: 16px; bottom: 7px; z-index: 3; font-family: var(--mono); font-size: 9px; letter-spacing: .03em; line-height: 1.2; color: var(--mute); opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
