@font-face { font-family: 'SamsungSharpSans'; src: url('assets/fonts/SamsungSharpSans-Bold.ttf') format('truetype'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'SamsungSharpSans'; src: url('assets/fonts/SamsungSharpSans-Medium.ttf') format('truetype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'SamsungOne'; src: url('assets/fonts/SamsungOne-400.ttf') format('truetype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'SamsungOne'; src: url('assets/fonts/SamsungOne-700.ttf') format('truetype'); font-weight: 700; font-display: swap; }

:root {
  /* display background: the Samsung blue of the event slides */
  --glow: #0042d2; --mid: #002eab; --edge: #001b80;
  /* B2B Connect 2026 event palette */
  --samsung-blue: #1428a0; --confident-blue: #020dcb; --deep-navy: #091039;
  --morning-sky: #eaf8fb; --lavender-veil: #f7e8ff; --frosted-mint: #e3ffe6;
  --ink: #091039; --muted: #4f5672; --line: #d6dcea; --card: #fff;
  --sky-ar: 3.057;   /* keyart.png width / height */
  --head: 'SamsungSharpSans', 'SamsungOne', system-ui, sans-serif;
  --body: 'SamsungOne', system-ui, sans-serif;
  --safe-b: max(16px, env(safe-area-inset-bottom));
}

/* ---------------- display ---------------- */
body.display {
  margin: 0; height: 100dvh; overflow: hidden; color: #fff; font-family: var(--body);
  background: radial-gradient(ellipse 80% 70% at 50% 38%, var(--glow) 0%, var(--mid) 48%, var(--edge) 100%);
  -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
}
.sky { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.glow { position: absolute; inset: -10%; background: radial-gradient(circle at 50% 36%, rgb(60 120 255 / .42), transparent 52%); }
.cloud-wrap { position: absolute; }
/* clouds float gently once the opening is over (each on its own rhythm), and hold still before that */
.cloud-wrap img { display: block; width: 100%; opacity: .55; animation: drift 9s cubic-bezier(.37, 0, .63, 1) infinite alternate; }
.cloud-tl2 img { animation-duration: 7.5s; }
body.booting .cloud-wrap img, body.intro .cloud-wrap img { animation-play-state: paused; }
/* the cloud art is cut where the source picture ended: those edges start far enough off-screen to stay
   hidden through the whole ±2vw drift, and fade out softly just in case */
.cloud-tl { top: 1%; left: -5vw; width: 34vw; }
.cloud-tl2 { top: 27%; left: -4.5vw; width: 14vw; }
.cloud-tr { top: 2%; right: -5vw; width: 27vw; }
.cloud-tl img, .cloud-tl2 img { -webkit-mask-image: linear-gradient(to right, transparent, #000 8%); mask-image: linear-gradient(to right, transparent, #000 8%); }
.cloud-tr img { -webkit-mask-image: linear-gradient(to left, transparent, #000 8%); mask-image: linear-gradient(to left, transparent, #000 8%); }
.cloud-tr img { animation-name: drift-r; animation-duration: 10s; }
@keyframes drift { to { transform: translate(2vw, -0.5vh); } }
@keyframes drift-r { to { transform: translate(-2vw, 0.4vh); } }
.skyline { position: absolute; left: 50%; bottom: 0; width: max(100vw, calc(30vh * var(--sky-ar))); aspect-ratio: var(--sky-ar);
  transform: translateX(-50%); opacity: .5; display: block; }   /* canvas: src/keyart.js draws and animates the key art */
/* QR view: calm the artwork so scanners only find one set of finder patterns */
.skyline, .cloud-tl, .cloud-tl2, .cloud-tr { transition: opacity .9s ease; }
body.qr .skyline { opacity: .08; }
body.qr .cloud-tl, body.qr .cloud-tl2, body.qr .cloud-tr { opacity: .15; }

#scene { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: manipulation; cursor: pointer; }

.brand { position: fixed; top: max(4vh, env(safe-area-inset-top)); left: 0; right: 0; padding: 0 16px; text-align: center; pointer-events: none; }
.brand h1 { font-family: var(--head); font-weight: 700; font-size: clamp(28px, 4vw, 84px); line-height: 1.06; letter-spacing: -0.015em; margin: 0; overflow-wrap: anywhere; }
.brand p { font-family: var(--head); font-weight: 500; font-size: clamp(16px, 1.65vw, 34px); margin: .4em 0 0; overflow-wrap: anywhere; }
/* default text: the key art's own lettering (exact match); the real text stays for screen readers */
.brand-art { display: block; margin: 0 auto; width: clamp(260px, 38vw, 1640px); height: auto; }
.brand.art h1, .brand.art p { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
.brand p:empty { display: none; }

.hint { position: fixed; left: 50%; bottom: calc(var(--safe-b) + 68px); transform: translateX(-50%); margin: 0;
  padding: 10px 20px; border-radius: 22px; font-size: clamp(15px, 1.2vw, 26px); font-weight: 700; line-height: 1.3; text-align: center;
  width: max-content; max-width: calc(100vw - 32px); box-sizing: border-box; pointer-events: none;
  background: rgb(255 255 255 / .14); border: 1px solid rgb(255 255 255 / .24); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: background .4s, color .4s; }
/* every state has the same box and type, so flipping views only changes colour and words (no jump) */
.hint.cta { background: #fff; color: var(--samsung-blue); }
.hint.opens-link { pointer-events: auto; cursor: pointer; }
.hint.opens-link::after { content: ''; display: inline-block; width: .8em; height: .8em; margin-left: .4em; vertical-align: -.05em; background: currentColor;
  -webkit-mask: var(--arrow) center / contain no-repeat; mask: var(--arrow) center / contain no-repeat;
  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5 3h8v8M13 3L3 13' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.hint.opens-link:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.controls { position: fixed; left: 50%; bottom: var(--safe-b); transform: translateX(-50%); display: flex; gap: 6px; padding: 6px;
  border-radius: 999px; background: rgb(255 255 255 / .12); border: 1px solid rgb(255 255 255 / .2);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: opacity .5s, transform .5s; }
body.idle .controls { opacity: 0; pointer-events: none; transform: translate(-50%, 14px); }
body.idle, body.idle #scene { cursor: none; }
.controls button { display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 14px; border: 0; border-radius: 999px;
  background: transparent; color: #fff; font: 500 14px var(--body); cursor: pointer; }
@media (hover: hover) { .controls button:hover { background: rgb(255 255 255 / .14); } }   /* touch: a tap would leave it stuck on */
.controls button[aria-pressed="true"] { background: #fff; color: var(--samsung-blue); }
.controls button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.controls[hidden], .controls button[hidden] { display: none; }
.controls svg { width: 18px; height: 18px; flex: none; }
.controls .sep { width: 1px; background: rgb(255 255 255 / .25); margin: 6px 2px; }
.controls .sep[hidden] { display: none; }

/* Seasonal sky light over the scene (lighting on, scene view only), all from the left where the scene's sun sits:
   spring morning haze, summer midday beams, autumn golden hour, winter blue hour */
.skylight > div { position: fixed; inset: 0; pointer-events: none; overflow: hidden; opacity: 0; transition: opacity 2.6s ease; }
body.lit:not(.qr):not(.intro):not(.booting)[data-season="spring"] .morning,
body.lit:not(.qr):not(.intro):not(.booting):not(.rain)[data-season="summer"] .sunrays,
body.lit:not(.qr):not(.intro):not(.booting)[data-season="autumn"] .evening,
body.lit:not(.qr):not(.intro):not(.booting)[data-season="autumn"] .evening-sky,
body.lit:not(.qr):not(.intro):not(.booting)[data-season="winter"] .dusk { opacity: 1; }
.skylight i { position: absolute; left: var(--x); top: var(--y); width: var(--w); height: 150vmax; transform-origin: 50% 0;
  background: linear-gradient(90deg, rgb(var(--c) / 0), rgb(var(--c) / var(--o)) 50%, rgb(var(--c) / 0));
  -webkit-mask-image: linear-gradient(to bottom, #000 8%, rgba(0, 0, 0, .55) 42%, transparent 78%);
  mask-image: linear-gradient(to bottom, #000 8%, rgba(0, 0, 0, .55) 42%, transparent 78%);
  animation: beam var(--d) ease-in-out infinite alternate; }
@keyframes beam { from { opacity: .45; transform: translateX(-50%) rotate(var(--a)); } to { opacity: 1; transform: translateX(-50%) rotate(calc(var(--a) + 2.5deg)); } }
@media (prefers-reduced-motion: reduce) { .skylight i { animation: none; transform: translateX(-50%) rotate(var(--a)); } }

/* spring morning: a low pale-gold sun at the left edge, long soft beams, a cool mist rising off the ground */
.morning { mix-blend-mode: screen; --c: 255 236 208; --x: -4vw; --y: 30vh; }
.morning::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 64vmax 46vmax at 0% 36%, rgba(255, 228, 200, .5), rgba(255, 228, 200, .16) 45%, rgba(255, 228, 200, 0) 75%); }
.morning::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(226, 242, 255, .22), rgba(226, 242, 255, 0) 40%); }
.morning i:nth-child(1) { --a: -74deg; --w: 16vmax; --o: .15; --d: 9s; }
.morning i:nth-child(2) { --a: -81deg; --w: 9vmax; --o: .18; --d: 7s; animation-delay: -3s; }
.morning i:nth-child(3) { --a: -87deg; --w: 20vmax; --o: .1; --d: 11s; animation-delay: -5s; }

.sunrays { mix-blend-mode: screen; --c: 255 240 205; --x: 12vw; --y: -20vh; }   /* summer midday: a high sun at the upper left; the tree's shafts lean the same way */
.sunrays::before { content: ''; position: absolute; left: calc(12vw - 36vmax); top: -48vmax; width: 72vmax; height: 72vmax; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 236, 196, .4), rgba(255, 226, 170, .13) 45%, rgba(255, 226, 170, 0)); }
.sunrays i:nth-child(1) { --a: -26deg; --w: 9vmax; --o: .14; --d: 7s; }
.sunrays i:nth-child(2) { --a: -31deg; --w: 4vmax; --o: .17; --d: 5.5s; animation-delay: -2s; }
.sunrays i:nth-child(3) { --a: -36deg; --w: 12vmax; --o: .11; --d: 8s; animation-delay: -4s; }
.sunrays i:nth-child(4) { --a: -41deg; --w: 5vmax; --o: .15; --d: 6.5s; animation-delay: -1s; }
.sunrays i:nth-child(5) { --a: -46deg; --w: 8vmax; --o: .09; --d: 9s; animation-delay: -3s; }

/* autumn evening: golden hour, a low amber sun at the left, long warm beams, the sky deepening to violet above */
.evening { mix-blend-mode: screen; --c: 255 170 88; --x: -6vw; --y: 44vh; }
.evening::before { content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 70vmax 48vmax at 0% 58%, rgba(255, 164, 76, .42), rgba(255, 128, 56, .14) 40%, rgba(255, 128, 56, 0) 72%),
    linear-gradient(100deg, rgba(255, 150, 70, .12), rgba(255, 150, 70, 0) 55%); }
.evening-sky { mix-blend-mode: multiply; background: linear-gradient(to bottom, rgba(92, 56, 150, .3), rgba(92, 56, 150, 0) 45%); }   /* its own layer: a blend inside a faded group can't reach the page */
.evening i:nth-child(1) { --a: -70deg; --w: 12vmax; --o: .14; --d: 8s; }
.evening i:nth-child(2) { --a: -77deg; --w: 6vmax; --o: .18; --d: 6s; animation-delay: -2s; }
.evening i:nth-child(3) { --a: -83deg; --w: 16vmax; --o: .1; --d: 10s; animation-delay: -4s; }
.evening i:nth-child(4) { --a: -88deg; --w: 7vmax; --o: .13; --d: 7.5s; animation-delay: -1s; }

/* winter blue hour: the sky dims to a deep cool blue while the palace's lamps glow warm in the snow (lit in the scene) */
.dusk { mix-blend-mode: multiply; background: linear-gradient(to bottom, rgba(18, 26, 86, .42), rgba(30, 44, 120, .14) 55%, rgba(18, 26, 86, .26)); }

/* ‹ › season steppers at the screen edges (desktop browsers); they idle-hide with the controls */
.season-arrow { position: fixed; top: 50%; margin-top: -26px; width: 52px; height: 52px; display: grid; place-items: center; padding: 0;
  border-radius: 50%; border: 1px solid rgb(255 255 255 / .2); background: rgb(255 255 255 / .12); color: #fff; cursor: pointer;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: opacity .5s, background .2s; }
@media (hover: hover) { .season-arrow:hover { background: rgb(255 255 255 / .24); } }
.season-arrow:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.season-arrow svg { width: 24px; height: 24px; }
#prev-season { left: clamp(12px, 2vw, 40px); }
#next-season { right: clamp(12px, 2vw, 40px); }
.season-arrow[hidden] { display: none; }
body.idle .season-arrow { opacity: 0; pointer-events: none; }
@media (pointer: coarse) { .season-arrow { display: none; } }

/* corner fullscreen button (season bar off): a small glass drop, faint until hovered */
.fs-corner { position: fixed; right: clamp(12px, 2vw, 32px); bottom: var(--safe-b); width: 44px; height: 44px; padding: 0;
  display: grid; place-items: center; border-radius: 50%; color: #fff; cursor: pointer; opacity: .7;
  border: 1px solid rgb(255 255 255 / .35);
  background: radial-gradient(120% 90% at 30% 15%, rgb(255 255 255 / .38), rgb(255 255 255 / .08) 55%, rgb(255 255 255 / .16));
  box-shadow: inset 0 1px 1px rgb(255 255 255 / .45), inset 0 -2px 6px rgb(0 20 80 / .18), 0 6px 18px rgb(0 10 60 / .22);
  backdrop-filter: blur(10px) saturate(170%); -webkit-backdrop-filter: blur(10px) saturate(170%);
  transition: opacity 1.2s ease, transform .2s; }
@media (hover: hover) { .fs-corner:hover { opacity: 1; transform: scale(1.06); } }
.fs-corner:focus-visible { outline: 2px solid #fff; outline-offset: 2px; opacity: 1; }
.fs-corner svg { width: 18px; height: 18px; }
.fs-corner[hidden] { display: none; }
body.idle .fs-corner { opacity: .45; }
body.fs.idle .fs-corner { opacity: 0; pointer-events: none; }   /* fullscreen: gone until the mouse moves */

.notice { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 20px 26px; border-radius: 20px;
  background: #fff; color: var(--ink); font-size: 16px; text-align: center; box-shadow: 0 10px 40px rgb(0 0 0 / .25); }
.notice a { color: var(--samsung-blue); font-weight: 700; }

/* start gate: one tap for fullscreen and/or sound (browsers require a gesture) */
.gate { position: fixed; inset: 0; z-index: 10; border: 0; background: transparent; color: #fff; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; font-family: var(--body); }
.gate[hidden] { display: none; }
.gate-pill { padding: 14px 28px; border-radius: 999px; background: #fff; color: var(--samsung-blue); font: 700 clamp(16px, 1.6vw, 28px) var(--body);
  box-shadow: 0 8px 30px rgb(0 0 0 / .25); animation: breathe 2.4s ease-in-out infinite; }
.gate-sub { font-size: clamp(13px, 1vw, 18px); opacity: .8; }
@keyframes breathe { 50% { transform: scale(1.05); } }
/* booting: until the script decides (start screen or intro), only the sky glow shows — no flash of the final layout */
body.booting .sky > :not(.glow), body.booting .brand, body.booting .hint, body.booting .controls, body.booting .season-arrow, body.booting .fs-corner { visibility: hidden; }

/* intro: the final state is the default; .intro animates in from each keyframe's 'from'. --pace scales it (slow / normal / fast) */
body.intro .glow { animation: glowIn calc(1.2s * var(--pace, 1)) ease-out both; }
body.intro .cloud-tl, body.intro .cloud-tl2 { animation: cloudL calc(1.6s * var(--pace, 1)) calc(.3s * var(--pace, 1)) cubic-bezier(.2,.7,.2,1) both; }
body.intro .cloud-tr { animation: cloudR calc(1.6s * var(--pace, 1)) calc(.45s * var(--pace, 1)) cubic-bezier(.2,.7,.2,1) both; }
/* title and controls wait (paused on 'from') until the script cues them: .brand-in during the palace build, .ui-in after */
body.intro .brand { animation: fadeUp calc(.9s * var(--pace, 1)) ease-out both paused; }
body.intro .hint, body.intro .controls { animation: fadeUpCentered calc(.6s * var(--pace, 1)) ease-out both paused; }
body.intro .season-arrow { animation: fadeUp calc(.6s * var(--pace, 1)) ease-out both paused; }
body.intro.brand-in .brand, body.intro.ui-in .hint, body.intro.ui-in .controls, body.intro.ui-in .season-arrow { animation-play-state: running; }
body.still-bg.intro .glow, body.still-bg.intro .cloud-tl, body.still-bg.intro .cloud-tl2, body.still-bg.intro .cloud-tr { animation: none; }
body.present:not(.qr) .hint { visibility: hidden; }   /* presentation mode: no pill over the palace; it shows under the QR */
body.intro:not(.ui-in) .fs-corner { opacity: 0; pointer-events: none; }   /* arrives with the controls */
@keyframes glowIn { from { opacity: 0; transform: scale(.85); } }
@keyframes cloudL { from { opacity: 0; transform: translateX(-10vw); clip-path: inset(0 100% 0 0); } }
@keyframes cloudR { from { opacity: 0; transform: translateX(10vw); clip-path: inset(0 0 0 100%); } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(12px); } }
@keyframes fadeUpCentered { from { opacity: 0; transform: translate(-50%, 12px); } }

@media (max-width: 720px), (orientation: portrait) {
  .brand h1 { font-size: clamp(26px, 8vw, 44px); }
  .brand p { font-size: clamp(15px, 4.2vw, 20px); }
  .brand-art { width: min(86vw, 560px); }
  .controls button .label { display: none; }
  .controls button { padding: 0 11px; }
  .cloud-tl { width: 52vw; } .cloud-tr { width: 42vw; } .cloud-tl2 { display: none; }
}
@media (prefers-reduced-motion: reduce) { .cloud-wrap img { animation: none; } }

/* ---------------- editor ---------------- */
body.editor { margin: 0; background: var(--morning-sky); color: var(--ink); font: 15px/1.5 var(--body); }
.ed-head { padding: 20px 24px; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.ed-head h1 { font: 700 22px var(--head); margin: 0; color: var(--samsung-blue); }
.ed-head span { color: var(--muted); }
.ed-grid { display: grid; grid-template-columns: minmax(300px, 400px) 1fr; gap: 20px; padding: 0 24px 24px; align-items: start; }
.card { background: var(--card); border-radius: 26px; padding: 22px; box-shadow: 0 1px 2px rgb(9 16 57 / .05), 0 8px 28px rgb(20 40 160 / .07); }
.field { display: grid; gap: 6px; margin-bottom: 16px; }
.field > span, fieldset legend { font-weight: 700; font-size: 13px; }
.field input[type=url], .field input[type=text], .field input[type=number], .field select {
  font: inherit; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: #fff; color: var(--ink); min-width: 0; }
.field input:focus-visible, .field select:focus-visible, .sub input:focus-visible { outline: 2px solid var(--samsung-blue); outline-offset: 1px; }
fieldset { border: 0; padding: 0; margin: 0 0 16px; display: grid; gap: 6px; }
.opt { display: flex; gap: 8px; align-items: center; }
.opt input { accent-color: var(--samsung-blue); }
.sub { display: flex; gap: 10px; align-items: center; color: var(--muted); font-size: 13px; padding-left: 24px; }
.sub[hidden], .opt[hidden] { display: none; }
.sub input { width: 72px; font: inherit; padding: 6px 8px; border: 1px solid var(--line); border-radius: 10px; }
.msg { font-size: 13px; min-height: 1.2em; margin: 0; }
.msg.err { color: #c62828; } .msg.warn { color: #9a6200; }
/* the preview is a real 1280×720 display, scaled to fit, so it always shows the big-screen layout */
.preview-wrap { position: relative; aspect-ratio: 16 / 9; width: 100%; border-radius: 18px; overflow: hidden; background: var(--edge); }
.preview { position: absolute; left: 0; top: 0; width: 1280px; height: 720px; border: 0; transform-origin: 0 0; transform: scale(var(--s, .5)); }
.out { display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: center; margin-top: 16px; }
.link { font: 13px ui-monospace, monospace; word-break: break-all; background: var(--morning-sky); padding: 10px 12px; border-radius: 12px; margin: 0 0 10px; }
.btns { display: flex; gap: 8px; flex-wrap: wrap; }
.btn { font: 700 14px var(--body); padding: 10px 18px; border-radius: 999px; border: 1px solid var(--samsung-blue); background: #fff; color: var(--samsung-blue); cursor: pointer; }
.btn.primary { background: var(--samsung-blue); color: #fff; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.sm { padding: 6px 14px; font-size: 13px; margin-left: auto; align-self: center; }
/* sign-in: the editor stays hidden until a gala organiser signs in */
body.locked .ed-grid { display: none; }
.login { display: grid; place-items: center; padding: 8vh 16px; }
.login[hidden] { display: none; }
.login-card { width: min(400px, 100%); }
.login-card h2 { font: 700 22px var(--head); margin: 0 0 4px; color: var(--samsung-blue); }
.login-card .muted { color: var(--muted); margin: 0 0 16px; }
.login-card .field input { font: inherit; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; }
.login-card .btn { width: 100%; }
.login-err { color: #c62828; font-size: 13px; min-height: 18px; margin: 0 0 10px; }
.login-help { font-size: 12px; margin: 14px 0 0 !important; }
#linkqr { width: 120px; height: 120px; image-rendering: pixelated; }
.note { color: var(--muted); font-size: 13px; margin: 12px 0 0; }
@media (max-width: 860px) { .ed-grid { grid-template-columns: 1fr; padding: 0 16px 16px; } .ed-head { padding: 16px; } .out { grid-template-columns: 1fr; } }
