/* Wedding Camera — guest interface.
 *
 * Class names inside the camera are scoped (.win .n, not a bare .n).
 * A bare .n previously collided with an unrelated rule and painted a
 * translucent box over the exposure counter; it was invisible in source
 * review and only found by measuring the rendered element.
 */

:root {
  --body-1: #C9DFF2;
  --body-2: #A9C9E6;
  --body-3: #93B8DC;
  --ink: #2C5678;
  --ink-soft: #3F6A8E;
  --deck-1: #4B535B;
  --deck-2: #333A41;
  --amber: #E8B563;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: #0E141A;
  font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

/* iOS paints a translucent square over a tapped element's bounding box,
   which looks broken on round camera controls. */
button {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-touch-callout: none;
  user-select: none; -webkit-user-select: none;
  font: inherit; color: inherit; cursor: pointer;
}
button:focus:not(:focus-visible) { outline: none; }
button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 3px solid #174F7C;
  outline-offset: 3px;
}

/* ============================== JOIN ============================== */
.join-body {
  background: linear-gradient(170deg, #EEF4FA 0%, #DCE9F5 100%);
  min-height: 100dvh;
  display: grid; place-items: center;
  padding: 24px 18px calc(24px + env(safe-area-inset-bottom));
}
.join {
  width: 100%; max-width: 420px;
  background: #fff;
  border: 1px solid #CBDDEC;
  border-radius: 14px;
  padding: 26px 22px 24px;
  box-shadow: 0 20px 50px -24px rgba(30,60,90,.45);
  text-align: center;
}
.crest-link { display: block; width: max-content; margin: 0 auto; border-radius: 8px; }
.join-crest { width: 92px; height: auto; display: block; margin: 0 auto 10px; }
.join h1 { margin: 0 0 6px; font-size: 25px; font-weight: 400; color: var(--ink); }
.join-lede { margin: 0 0 20px; font-size: 14.5px; line-height: 1.55; color: var(--ink-soft);
  font-family: -apple-system, system-ui, sans-serif; }
.join-form { display: flex; flex-direction: column; gap: 6px; text-align: left; }
.join-form label {
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-soft); font-weight: 700; margin-top: 10px;
}
.join-form label .opt { text-transform: none; letter-spacing: 0; font-weight: 400; opacity: .7; }
.join-form input {
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 16px; /* 16px or iOS zooms the page on focus */
  padding: 12px 13px;
  border: 1px solid #C3D6E6; border-radius: 8px;
  background: #FBFDFF; color: #16222C;
}
.join-form input:focus { outline: 2px solid #6E9EC9; outline-offset: 1px; }
.join-note {
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 12.5px; line-height: 1.5; color: #6B8199; margin: 8px 0 4px;
}
.join-form button {
  margin-top: 14px; padding: 15px;
  border: none; border-radius: 9px;
  background: linear-gradient(178deg, #4C7BA5, #375F84);
  color: #fff; font-family: -apple-system, system-ui, sans-serif;
  font-size: 16px; font-weight: 700; letter-spacing: .03em;
}
.join-form button:active { transform: translateY(1px); }
.join-error {
  background: #FDECEC; border: 1px solid #E9B8B8; color: #8A2F2F;
  border-radius: 8px; padding: 10px 12px; font-size: 14px;
  font-family: -apple-system, system-ui, sans-serif;
}

/* ============================= CAMERA ============================= */
/* The whole camera must fit the viewport on every phone. Phones vary far
   more in height than width, and if the shutter falls below the fold the
   guest has to scroll to take a photograph — losing sight of the
   exposure counter on the way. So: fixed to the viewport, no page
   scrolling, and the viewfinder absorbs whatever height is left over. */
.cam-body {
  height: 100dvh;
  overflow: hidden;
  display: flex; align-items: stretch; justify-content: center;
  padding: 0;
  position: fixed; inset: 0;         /* stops iOS rubber-band scrolling */
}
.cam {
  position: relative;
  width: 100%; max-width: 480px;
  height: 100%;
  display: flex; flex-direction: column;
  background: linear-gradient(163deg, var(--body-1) 0%, var(--body-2) 44%, var(--body-3) 100%);
  overflow: hidden;
  padding-bottom: env(safe-area-inset-bottom);
}
/* Moulded glossy plastic on the BODY only: z-index 2, below every
   mounted component. A highlight over the black counter washes it out. */
.cam::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    linear-gradient(116deg, rgba(255,255,255,.50) 0%, rgba(255,255,255,.20) 13%,
                    rgba(255,255,255,.03) 27%, rgba(255,255,255,0) 40%),
    linear-gradient(298deg, rgba(255,255,255,.26) 0%, rgba(255,255,255,0) 30%),
    linear-gradient(180deg, rgba(255,255,255,.18) 0%, rgba(255,255,255,0) 26%,
                    rgba(20,45,70,.05) 68%, rgba(20,45,70,.12) 100%);
}

.deck {
  position: relative; z-index: 3;
  background: linear-gradient(180deg, var(--deck-1), var(--deck-2));
  padding: calc(11px + env(safe-area-inset-top)) 16px 12px;
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid rgba(0,0,0,.4);
}
.deck-grp { display: flex; align-items: center; gap: 12px; }

.wheel {
  width: 44px; height: 44px; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, #2E353B 0deg 7deg, #3D454C 7deg 14deg), #333A41;
  border: 1px solid #4B535A; box-shadow: inset 0 0 7px rgba(0,0,0,.6);
  transition: transform .5s cubic-bezier(.22,.9,.3,1);
}

.knob {
  -webkit-appearance: none; appearance: none; padding: 0;
  width: 40px; height: 40px; border-radius: 50%;
  background: radial-gradient(circle at 50% 33%, #48505A, #21262B);
  border: 1px solid #565E66; display: grid; place-items: center;
  transition: box-shadow .18s ease;
}
.knob svg { width: 17px; height: 17px; }
.knob .ic { fill: #6B757E; transition: fill .16s ease, filter .16s ease; }
.knob .slash { stroke: #6B757E; stroke-width: 2.1; stroke-linecap: round; transition: opacity .16s ease; }
.knob[aria-pressed="true"] { box-shadow: 0 0 0 2px rgba(232,181,99,.45); }
.knob[aria-pressed="true"] .ic { fill: var(--amber); filter: drop-shadow(0 0 4px rgba(232,181,99,.75)); }
.knob[aria-pressed="true"] .slash { opacity: 0; }
.knob:focus-visible { outline: 2px solid #9FD0FF; outline-offset: 2px; }

.win {
  background: #0B0E12; border: 1px solid #4A525A; border-radius: 3px;
  padding: 5px 11px 4px; text-align: center; min-width: 64px;
  box-shadow: inset 0 1px 5px rgba(0,0,0,.9);
  position: relative; z-index: 1;
}
.win .n {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 16px; color: var(--amber); line-height: 1; letter-spacing: .05em;
}
.win .t {
  display: block; margin-top: 2px;
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 6.5px; letter-spacing: .2em; text-transform: uppercase; color: #79838D;
}

/* flex:1 + min-height:0 is what lets the viewfinder shrink on a short
   phone instead of pushing the shutter off the bottom. */
.mid {
  position: relative; z-index: 3;
  flex: 1 1 auto; min-height: 0;
  display: flex; gap: 8px; padding: 12px 14px 0;
}

.finder {
  flex: 1 1 auto; min-width: 0; min-height: 0;
  position: relative; z-index: 7;
  border-radius: 4px; overflow: hidden; background: #0D1216;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.2), 0 4px 12px rgba(25,45,68,.4);
}
.finder video { width: 100%; height: 100%; object-fit: cover; display: block; }
.finder.selfie video { transform: scaleX(-1); }

.grid { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.grid span { position: absolute; background: rgba(255,255,255,.24); }
.grid span.v { top: 0; bottom: 0; width: 1px; }
.grid span.h { left: 0; right: 0; height: 1px; }
.grid span.v:nth-child(1) { left: 33.333%; }
.grid span.v:nth-child(2) { left: 66.666%; }
.grid span.h:nth-child(3) { top: 33.333%; }
.grid span.h:nth-child(4) { top: 66.666%; }

.marks { position: absolute; inset: 8px; pointer-events: none; z-index: 3; }
.marks i { position: absolute; width: 15px; height: 15px; border: 1.5px solid rgba(255,255,255,.55); }
.marks i:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.marks i:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.marks i:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.marks i:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; }

.pop { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; z-index: 8; }
.pop.fire { animation: pop .34s ease-out; }
@keyframes pop { 0% { opacity: 0 } 12% { opacity: .95 } 100% { opacity: 0 } }

/* departing frame, carrying a preview of the film look the server bakes in */
.fly { position: absolute; inset: 0; z-index: 6; opacity: 0; pointer-events: none; overflow: hidden; border-radius: 3px; }
.fly canvas { width: 100%; height: 100%; object-fit: cover; display: block;
  filter: sepia(.30) saturate(1.45) contrast(1.04) brightness(1.06) hue-rotate(-7deg); }
.fly .warm { position: absolute; inset: 0; mix-blend-mode: screen;
  background: radial-gradient(120% 85% at 50% 42%, rgba(255,214,150,.20), transparent 62%),
              linear-gradient(200deg, rgba(255,176,94,.14), rgba(84,58,120,.10)); }
.fly .lift { position: absolute; inset: 0; background: rgba(122,104,80,.10); }
.fly .vig { position: absolute; inset: 0;
  background: radial-gradient(125% 92% at 50% 48%, transparent 52%, rgba(28,16,8,.42) 100%); }
.fly .grain { position: absolute; inset: 0; opacity: .30; mix-blend-mode: overlay;
  background-image: radial-gradient(rgba(255,255,255,.9) .5px, transparent .5px),
                    radial-gradient(rgba(0,0,0,.9) .5px, transparent .5px);
  background-size: 3px 3px, 4px 4px; background-position: 0 0, 1px 2px; }
.fly .stamp-top, .fly .stamp-date {
  position: absolute; font-family: ui-monospace, Menlo, Consolas, monospace;
  color: #FF9A2E; text-shadow: 0 0 5px rgba(255,140,30,.85); letter-spacing: .1em;
}
.fly .stamp-top { top: 10px; left: 0; right: 0; text-align: center; font-size: 9px;
  text-transform: uppercase; letter-spacing: .17em; }
.fly .stamp-date { right: 10px; bottom: 9px; font-size: 10px; font-variant-numeric: tabular-nums; }
.fly.go { animation: flyk 1.5s cubic-bezier(.5,.02,.3,1) forwards; }
@keyframes flyk {
  0%   { opacity: 1; transform: translate(0,0) rotate(0) scale(1); }
  10%  { opacity: 1; transform: translate(0,-8px) rotate(-1.6deg) scale(.985); }
  45%  { opacity: 1; transform: translate(0,-8px) rotate(-1.6deg) scale(.985); }
  100% { opacity: 0; transform: translate(134%,-32%) rotate(16deg) scale(.68); }
}

/* The hidden attribute must beat any class that sets display. The browser's
   own rule is [hidden]{display:none}, but that is a lower-specificity
   attribute selector than a class, so `.permission{display:grid}` silently
   outranked it — element.hidden = true had no effect and the overlay sat
   over the viewfinder permanently, hiding the very thing being framed.
   Declared here, before the components, so every hideable element is safe. */
[hidden] { display: none !important; }

.permission { position: absolute; inset: 0; z-index: 9; display: grid; place-items: center;
  background: rgba(10,16,22,.94); padding: 22px; }
.permission-inner { text-align: center; max-width: 300px; }
.permission p { color: #E7EEF5; font-size: 15px; line-height: 1.55; margin: 0 0 16px;
  font-family: -apple-system, system-ui, sans-serif; }
.permission button { padding: 13px 22px; border: none; border-radius: 9px;
  background: #4C7BA5; color: #fff; font-family: -apple-system, system-ui, sans-serif;
  font-size: 15px; font-weight: 700; }

.rail {
  writing-mode: vertical-rl; font-size: 8.3px; line-height: 1.45;
  font-family: -apple-system, system-ui, sans-serif;
  letter-spacing: .045em; color: var(--ink-soft);
  max-height: 100%; padding-left: 3px; flex-shrink: 0; opacity: .85;
}
.rail b { font-weight: 700; letter-spacing: .1em; color: var(--ink); }

.status {
  position: relative; z-index: 3; margin: 10px 14px 0; text-align: center;
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 11.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-soft); font-weight: 700; min-height: 15px;
}
.status[data-s="send"] { color: #2F6E96; }
.status[data-s="ok"]   { color: #2F7A5E; }
.status[data-s="wait"] { color: #A9702A; }

.queue {
  position: relative; z-index: 3; margin: 7px 14px 0;
  background: rgba(255,255,255,.62); border: 1px solid rgba(90,128,164,.4);
  border-radius: 7px; padding: 7px 10px; text-align: center;
  font-family: -apple-system, system-ui, sans-serif; font-size: 11.5px;
  color: #23557C; font-weight: 600;
}

.storage-warning {
  position: relative; z-index: 3; margin: 7px 14px 0;
  background: #FFF6E8; border: 1px solid #D49A47;
  border-radius: 7px; padding: 8px 10px; text-align: center;
  font-family: -apple-system, system-ui, sans-serif; font-size: 12px;
  line-height: 1.35; color: #704514; font-weight: 650;
}

.plate {
  position: relative; z-index: 3; margin: 11px 14px 0;
  background: rgba(255,255,255,.9); border: 1px solid rgba(120,158,190,.45);
  border-radius: 4px; padding: 8px 12px;
  display: flex; align-items: center; gap: 12px;
}
.plate .who { flex: 1; min-width: 0; text-align: right; }
.plate .nm { font-size: 16px; line-height: 1.14; color: var(--ink); text-wrap: balance; }
.plate .dt { font-family: -apple-system, system-ui, sans-serif; font-size: 8.5px;
  letter-spacing: .17em; text-transform: uppercase; color: var(--ink-soft); margin-top: 3px; }
.plate img { width: 54px; height: auto; display: block; flex-shrink: 0; }

.base {
  position: relative; z-index: 3;
  padding: 12px 20px 14px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.switch {
  -webkit-appearance: none; appearance: none; padding: 0;
  width: 46px; height: 46px; border-radius: 50%;
  background: rgba(255,255,255,.5); border: 1px solid rgba(90,128,164,.45);
  color: var(--ink); display: grid; place-items: center; flex-shrink: 0;
}
.switch svg { width: 22px; height: 22px; }
.switch:focus-visible { outline-color: #174F7C; }

.shutter {
  -webkit-appearance: none; appearance: none; padding: 0;
  width: 74px; height: 74px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(178deg, #40464C 0%, #2A2F34 38%, #191D21 100%);
  border: 1px solid #12161A;
  box-shadow: 0 5px 13px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.14),
              inset 0 -4px 9px rgba(0,0,0,.55);
  display: grid; place-items: center;
  transition: transform .09s ease, box-shadow .09s ease;
}
.shutter::after {
  content: ""; width: 48px; height: 48px; border-radius: 50%;
  background: linear-gradient(178deg, #2E3338, #1B1F23);
  box-shadow: inset 0 2px 5px rgba(0,0,0,.7), 0 1px 0 rgba(255,255,255,.08);
}
.shutter:active { transform: translateY(2px) scale(.97); }
.shutter:disabled { opacity: .45; }
.shutter:focus-visible { outline: 3px solid #2C5678; outline-offset: 3px; }

.lens {
  width: 46px; height: 46px; border-radius: 50%; flex-shrink: 0;
  background: radial-gradient(circle at 42% 34%, #4C555D 0%, #262C32 46%, #13171B 100%);
  box-shadow: 0 0 0 3px #39424B, 0 0 0 4px rgba(255,255,255,.22), inset 0 2px 6px rgba(0,0,0,.7);
  display: grid; place-items: center;
}
.lens::after {
  content: ""; width: 16px; height: 16px; border-radius: 50%;
  background: radial-gradient(circle at 36% 30%, rgba(190,222,250,.75), rgba(40,70,100,.5) 55%, #0A0E12 100%);
}

.foot {
  position: relative; z-index: 3; text-align: center;
  padding: 0 14px 12px;
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase; color: #4C769B;
}

/* ---------------------------------------------------------------------
   Short phones. Everything below the viewfinder is chrome; on a cramped
   screen it gives up space in order of how little it is needed, so the
   viewfinder and the shutter always survive.
   --------------------------------------------------------------------- */
@media (max-height: 780px) {
  .deck { padding-top: calc(8px + env(safe-area-inset-top)); padding-bottom: 9px; }
  .mid { padding: 10px 12px 0; }
  .plate { margin-top: 8px; padding: 6px 10px; }
  .plate .nm { font-size: 14.5px; }
  .plate img { width: 44px; }
  .base { padding: 9px 18px 10px; }
  .shutter { width: 66px; height: 66px; }
  .shutter::after { width: 42px; height: 42px; }
  .foot { padding-bottom: 8px; }
}

@media (max-height: 680px) {
  /* The name plate is decoration; the counter and shutter are not. */
  .plate { display: none; }
  .foot { display: none; }
  .rail { display: none; }
  .status { margin-top: 7px; font-size: 10.5px; }
  .base { padding: 8px 16px 10px; }
  .wheel { display: none; }
}

@media (max-height: 580px) {
  .shutter { width: 58px; height: 58px; }
  .shutter::after { width: 36px; height: 36px; }
  .lens, .switch { width: 38px; height: 38px; }
  .mid { padding: 8px 10px 0; }
}

/* Landscape: guests will turn the phone. Keep the shutter reachable by
   putting the controls beside the viewfinder rather than beneath it. */
@media (orientation: landscape) and (max-height: 520px) {
  .cam { flex-direction: row; }
  .deck {
    flex-direction: column; justify-content: flex-start; gap: 12px;
    padding: calc(10px + env(safe-area-inset-top)) 10px 10px;
    border-bottom: none; border-right: 1px solid rgba(0,0,0,.4);
  }
  .deck-grp { flex-direction: column; }
  .mid { padding: 10px; }
  .rail, .plate, .foot, .status, .queue { display: none; }
  .storage-warning {
    position: absolute; left: 76px; right: 76px; bottom: 8px;
    margin: 0; font-size: 10px; padding: 5px 7px;
  }
  .base { flex-direction: column; padding: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .fly.go { animation: none; opacity: 0; }
  .pop.fire { animation: none; }
  .wheel { transition: none; }
}
