/* The way in: load the cylinder (js/signin.js). board.css still styles the punch-in scene; everything here lives
   under .gsi, and the few si- names the check scripts look for (.si-card, .si-msg, .si-name, .si-input) are reset. */

@property --turn {
  syntax: '<angle>';
  inherits: true;
  initial-value: 0deg;
}

.gsi { background: #070605; }
.gsi.leaving { opacity: 0; transition: opacity 0.65s ease; }

/* ---- the photograph ---- */

.gsi-back {
  position: absolute;
  inset: -40px;
  background-size: cover;
  background-position: 50% 48%;
  filter: blur(22px) brightness(0.72) saturate(0.95);
}
.gsi-view { position: absolute; inset: 0; transform-origin: 50% 48%; }
/* Where the photograph doesn't reach the window's edge, its edge melts into the blurred copy behind it. */
.gsi-view.fade-y .gsi-frame {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
}
.gsi-view.fade-x .gsi-frame {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.gsi-view.fade-x.fade-y .gsi-frame {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent), linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent), linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* A phone held upright: the photograph's own wood border at the top and foot is faded out with it. */
.gsi.upright .gsi-view.fade-y .gsi-frame {
  -webkit-mask-image: linear-gradient(180deg, transparent 4%, #000 15%, #000 86%, transparent 94.5%);
  mask-image: linear-gradient(180deg, transparent 4%, #000 15%, #000 86%, transparent 94.5%);
}
/* Leaving: the lamp seems to go down and the cylinder is gone from under you, as the shop comes up. */
.gsi.leaving .gsi-view { transform: scale(1.045); filter: brightness(0.55); transition: transform 0.65s cubic-bezier(.4, 0, .6, 1), filter 0.65s ease-in; }
.gsi.leaving .gsi-tag, .gsi.leaving .gsi-name { transform: translateY(-10px) rotate(var(--tilt, 0deg)); transition: transform 0.65s ease-in; }

.gsi-frame { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.gsi-plate { position: absolute; inset: 0; width: 100%; height: 100%; user-select: none; }

/* The oil lamp breathes a little (never a flicker). */
.gsi-glow {
  position: absolute;
  width: 1300px;
  height: 1300px;
  margin: -650px 0 0 -650px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 196, 120, 0.13), rgba(255, 160, 80, 0.045) 38%, transparent 68%);
  mix-blend-mode: screen;
  pointer-events: none;
  animation: gsi-breathe 6s ease-in-out infinite alternate;
}
@keyframes gsi-breathe { from { opacity: 0.7; transform: scale(0.985); } to { opacity: 1; transform: scale(1.015); } }

/* ---- the cylinder's face (turns on the pin) ---- */

.gsi-cyl {
  position: absolute;
  transform: rotate(var(--turn));
  will-change: transform;
}
.gsi-face { position: absolute; inset: 0; width: 100%; height: 100%; user-select: none; }
.gsi-ch { position: absolute; }

/* A cartridge in its chamber. .gsi-up turns against the cylinder so its light and shadow stay with the lamp. */
.gsi-round, .gsi-up, .gsi-lift { position: absolute; inset: 0; }
.gsi-up { transform: rotate(calc(-1 * var(--turn))); }
.gsi-lift {
  /* the rim stands a hair proud of the face: a tight shadow away from the lamp, and a soft one round it */
  filter: drop-shadow(7px 9px 5px rgba(0, 0, 0, 0.7)) drop-shadow(0 0 4px rgba(0, 0, 0, 0.55));
}
.gsi-lift img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  user-select: none;
  /* Brass under a lamp, matched to the cartridges in the box: darker and warmer than the studio photograph, a touch
     brighter on the lamp's side of the cylinder. */
  filter: brightness(calc(0.56 + 0.07 * cos(calc(var(--turn) + var(--a) - 225deg)))) sepia(0.42) saturate(1.3) hue-rotate(-5deg) contrast(1.22);
}
/* The lamp's light falls across the head from the top left. */
.gsi-lift::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(120% 120% at 24% 20%, rgba(255, 210, 140, 0.16), transparent 42%, rgba(18, 8, 0, 0.42) 100%);
  pointer-events: none;
}

/* The figure stamped into the head, between the primer and the rim. The box stays upright (so the stamp's lit and
   shaded walls stay with the lamp); the figure inside turns with the cylinder. */
.gsi-stampbox {
  position: absolute;
  inset: 0;
  filter: drop-shadow(1.5px 1.5px 0 rgba(255, 222, 150, 0.32)) drop-shadow(-1px -1px 0 rgba(20, 10, 0, 0.55));
}
.gsi-stamp {
  position: absolute;
  inset: 0;
  transform: rotate(calc(var(--turn) - var(--load)));
}
.gsi-fig {
  position: absolute;
  left: 50%;
  top: 9%;
  width: 80px;
  margin-left: -40px;
  text-align: center;
  font: 900 64px/1 'Cinzel', Georgia, serif;
  color: rgba(58, 36, 8, 0.86);
  user-select: none;
}

/* ---- the shop's name: an engraved brass plate lying on the baize ---- */

.gsi-name {
  position: absolute;
  z-index: 3;
  padding: 8px 6px 7px;
  border-radius: 0;
  font: 700 clamp(0.82rem, 1.1vw, 1.02rem)/1.2 'Cinzel', Georgia, serif;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #2a1b07;
  text-shadow: 0 1px 0 rgba(255, 238, 185, 0.55), 0 -1px 0 rgba(40, 24, 2, 0.35);
  /* a photograph of a real blank plate (assets/sprites/nameplate.webp, a ChatGPT cut-out) stretched between its
     screws; only the lettering is the page's */
  border-style: solid;
  border-color: transparent;
  border-width: 0 34px;
  border-image: url('/assets/sprites/nameplate.webp?v=10f9413ce2') 0 96 0 96 fill / 0 34px stretch;
  background: none;
  box-shadow: none;
  filter: brightness(0.9) drop-shadow(3px 5px 5px rgba(0, 0, 0, 0.6));
  pointer-events: none;
  transform-origin: 0 0;
  animation: gsi-in 0.9s 0.2s ease-out both;
}
@keyframes gsi-in { from { opacity: 0; } }

/* ---- the paper string tag ---- */

.gsi-tag,
.gsi .gsi-tag.si-card {
  /* reset what board.css gives its time card */
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  bottom: auto;
  width: min(300px, calc(100vw - 36px));
  margin: 0;
  padding: 0;
  background: none;
  box-shadow: none;
  border-radius: 0;
  color: #2b2213;
  cursor: default;
  --tilt: -4deg;
  transform: rotate(var(--tilt));
  animation: gsi-tag-in 0.8s 0.35s cubic-bezier(.2, .8, .25, 1) both;
  filter: drop-shadow(4px 7px 6px rgba(0, 0, 0, 0.55)) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
  pointer-events: none;
}
.gsi-tag.read { --tilt: -2.5deg; animation: none; }
.gsi-tag[data-side='below'] { --tilt: -1.5deg; }
@keyframes gsi-tag-in { from { opacity: 0; transform: translate3d(40px, 26px, 0) rotate(5deg); } }

.gsi-paper {
  position: relative;
  padding: 12px 18px 13px 46px;
  min-height: 74px;
  background-color: #c4ab72;
  background-image:
    linear-gradient(115deg, rgba(255, 246, 220, 0.28), transparent 45%, rgba(70, 45, 10, 0.18)),
    var(--img-manila, none);
  background-size: auto, 520px 520px;
  background-blend-mode: normal, multiply;
  filter: brightness(0.86);
  /* a shipping tag: the eyelet end cut off at the corners, and the hole through it */
  clip-path: polygon(22px 0, 100% 0, 100% 100%, 22px 100%, 0 calc(100% - 22px), 0 22px);
  -webkit-mask-image: radial-gradient(circle at 21px 50%, transparent 5.5px, #000 6.5px);
  mask-image: radial-gradient(circle at 21px 50%, transparent 5.5px, #000 6.5px);
}
/* the card washer round the hole */
.gsi-paper::before {
  content: '';
  position: absolute;
  left: 9px;
  top: 50%;
  width: 24px;
  height: 24px;
  margin-top: -12px;
  border-radius: 50%;
  background: radial-gradient(circle, transparent 0 6px, rgba(120, 82, 30, 0.55) 6.5px 7.5px, #c9ad6e 8px 11px, rgba(90, 60, 20, 0.5) 11.5px 12px);
}
/* the string through the eyelet, trailing off over the baize (board.css's notch on .si-card reset too) */
.gsi .gsi-tag::before {
  content: '';
  margin: 0;
  background: none;
  position: absolute;
  z-index: -1;
  left: -56px;
  top: calc(50% - 22px);
  width: 82px;
  height: 40px;
  border: 2.5px solid transparent;
  border-top-color: #a8987a;
  border-left-color: #9c8c6c;
  border-radius: 60% 40% 50% 50%;
  transform: rotate(-24deg);
}
.gsi .gsi-tag[data-side='below']::before { left: -40px; top: calc(50% - 30px); transform: rotate(-60deg); }

.gsi-hint {
  margin: 0;
  font: 600 1.42rem/1.1 var(--font-hand);
  color: #2f2a22;
}
.gsi .si-msg {
  min-height: 0;
  margin: 4px 0 0;
  font: 600 1.18rem/1.1 var(--font-hand);
  color: #8e1f1a;
}
.gsi .si-msg:empty { display: none; }
.gsi .si-msg.bad { color: #8e1f1a; }

.gsi .si-read { opacity: 1; transform: none; transition: none; }
.gsi .si-name { font: 1.3rem/1.15 var(--font-type); color: #1f1910; }
.gsi .si-rank { margin-top: 2px; font: 700 0.72rem/1.2 var(--font-stencil); letter-spacing: 0.2em; text-transform: uppercase; color: rgba(43, 34, 19, 0.75); }
.gsi .si-state { margin: 6px 0 0; font: 600 1.18rem/1.12 var(--font-hand); color: #2f2a22; }

/* The real field covers the screen (a tap anywhere brings up a phone's number pad); its own text is hidden. */
.gsi .si-input {
  position: absolute;
  z-index: 2;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  padding: 0;
  font-size: 16px;
  caret-color: transparent;
  cursor: default;
  background: transparent;
  color: transparent;
}
.gsi .si-input:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .gsi-glow, .gsi-name, .gsi-tag { animation: none; }
  .gsi.leaving .gsi-view, .gsi.leaving .gsi-tag, .gsi.leaving .gsi-name { transform: none; transition: none; }
}

@media (max-width: 560px) {
  .gsi-name { font-size: 0.86rem; padding: 7px 4px 6px; }
  .gsi-hint { font-size: 1.32rem; }
}
