/* ==========================================================================
   samisee.design, TAKEOVERS (crash, gn, hack, credits), foil mode, and the
   document windows (patch_notes.md, help). Logic in js/overlays.js.
   ========================================================================== */

#w-patch-notes, #w-help { width: 500px; height: 560px; }

.takeover {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  opacity: 0; transition: opacity 300ms var(--ease-standard);
}
.takeover[data-open] { opacity: 1; }
.takeover[hidden] { display: none; }

/* ---- crash: a blue screen in the site's own blue. Sami grew up on Windows ---- */
.bsod { display: grid; place-items: center; background: oklch(0.46 0.13 256); color: #fff; cursor: default; }
.bsod__in { width: min(640px, calc(100vw - 48px)); }
.bsod__face { margin: 0 0 28px; font: 300 clamp(80px, 14vw, 140px)/1 var(--font-body); }
.bsod__title { margin: 0 0 22px; font: var(--weight-display) clamp(22px, 3vw, 30px)/1.25 var(--font-display); }
.bsod__detail, .bsod__recover, .bsod__press { margin: 0 0 10px; font: 400 var(--text-body)/1.5 var(--font-mono); opacity: .85; }
.bsod__press { margin-top: 30px; opacity: .6; }
.bsod[data-open] .bsod__in { animation: bsod-in 260ms var(--ease-enter); }
@keyframes bsod-in { from { opacity: 0; scale: .98; } }

/* the beat before it (js/overlays.js, crash): hiccup, tear, cut */
.glitch-defs { position: absolute; width: 0; height: 0; }
body[data-glitch="hiccup"] :is(.wp, .wp-plate, .menubar, .icons, .dock, .specs, .sticker, .stk-item, .win[data-open]) {
  transform: translate(2px, -2px); filter: brightness(1.6) saturate(0);
}
body[data-glitch="tear"] :is(.wp, .wp-plate, .menubar, .icons, .dock, .specs, .sticker, .stk-item, .win[data-open]) {
  filter: url(#glitch-tear) drop-shadow(4px 0 0 rgb(255 40 110 / .7)) drop-shadow(-4px 0 0 rgb(40 220 255 / .7));
  animation: jolt 110ms steps(2) infinite;
}
/* transform, not translate: the dock and the plate already use translate to centre themselves */
@keyframes jolt { 0% { transform: translate(3px, 0); } 50% { transform: translate(-5px, 1px); } 100% { transform: translate(1px, -1px); } }

.glitch-fx { position: fixed; inset: 0; z-index: var(--z-overlay); pointer-events: none; overflow: hidden; }
.glitch-fx[hidden] { display: none; }
/* scanlines, always on while it glitches */
.glitch-fx::before {
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(0deg, rgb(0 0 0 / .28) 0 1px, transparent 1px 3px);
}
.glitch-fx i { position: absolute; mix-blend-mode: difference; opacity: 0; }
.glitch-fx[data-phase="hiccup"] { background: rgb(255 255 255 / .22); }
.glitch-fx[data-phase="cut"] { background: #000; }

/* ---- gn: lights out ---- */
.gn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: oklch(0.11 0.02 297); color: var(--os-accent); cursor: pointer;
}
.gn svg { width: 46px; height: 46px; filter: drop-shadow(0 0 22px color-mix(in srgb, var(--os-accent) 55%, transparent)); }
.gn__line { margin: 0; font: 500 var(--text-lead)/1.4 var(--font-mono); letter-spacing: var(--track-wide); text-transform: uppercase; }
.gn__hint { margin: 0; font: 400 var(--text-caption)/1 var(--font-mono); letter-spacing: var(--track-label); color: var(--os-ink-dim); }

/* ---- hack: green on black, types like it means it ---- */
.hack { background: #050806; padding: 6vh 6vw; cursor: pointer; }
.hack pre { margin: 0; font: 400 clamp(13px, 1.4vw, 17px)/1.7 var(--font-mono); color: #3dff7a; white-space: pre-wrap; text-shadow: 0 0 8px #3dff7a88; }
.hack pre::after { content: "▌"; animation: caret 1s steps(1) infinite; }
.hack[data-jk] pre { color: var(--os-accent-3); text-shadow: 0 0 10px color-mix(in srgb, var(--os-accent-3) 60%, transparent); }
.hack[data-jk] pre::after { content: none; }

/* ---- credits: the signature writes itself, then the roll ---- */
.credits { overflow: hidden; background: color-mix(in srgb, var(--os-sky-stop-1) 94%, transparent); cursor: pointer; }
.credits__roll {
  position: absolute; left: 50%; top: 0; width: min(560px, calc(100vw - 48px)); translate: -50% 0;
  text-align: center; animation: roll 22s linear forwards;
}
.credits__sig { width: min(340px, 70vw); margin: 0 auto 64px; }
.credits__sig .sig { display: block; width: 100%; height: auto; }
.credits__sig .sig__ink { fill: var(--os-ink); }
.credits__roll p { margin: 0 0 30px; font: var(--weight-display) var(--text-subhead)/1.3 var(--font-display); color: var(--os-ink); }
.credits__roll i { display: block; margin-bottom: 6px; font: 400 var(--text-caption)/1 var(--font-mono); font-style: normal; letter-spacing: var(--track-wide); text-transform: uppercase; color: var(--os-accent); }
.credits__end { margin-top: 70px !important; font: 400 clamp(36px, 6vw, 64px)/1 var(--font-accent) !important; color: var(--os-accent) !important; }
@keyframes roll { from { transform: translateY(100vh); } to { transform: translateY(-100%); } }

/* ---- a missing page: a mac alert in the site's glass. Centred icon, bold title,
   one quiet line, two equal buttons, OK on the right. A light scrim keeps the
   desktop in view, a touch above centre like the mac's own ---- */
.alert {
  display: grid; place-items: center; padding: 0 16px 8vh;
  background: color-mix(in srgb, var(--shade) 22%, transparent);
}
.alert__box {
  --lg-r: 26px; --lg-tint: 82%; --lg-blur: 30px;
  box-sizing: border-box; width: min(272px, calc(100vw - 32px)); padding: 22px 18px 16px; text-align: center;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--os-ink) 6%, transparent), transparent 40%),
    var(--window-fill);
}
.alert[data-open] .alert__box { animation: alert-in 260ms var(--ease-enter); }
@keyframes alert-in { from { opacity: 0; scale: .9; } }
.alert__ico { display: block; width: 56px; height: 56px; margin: 0 auto 14px; --ico-sw: 1.5; }
.alert__title { margin: 0 0 8px; font: 600 var(--text-lead)/1.35 var(--font-body); color: var(--os-ink); overflow-wrap: anywhere; }
.alert__detail { margin: 0 0 18px; font: 400 var(--text-body)/1.5 var(--font-body); color: var(--os-ink-dim); }
.alert__buttons { display: flex; gap: 8px; }
.alert__buttons .btn { flex: 1; justify-content: center; }

/* ---- foil mode (konami). Four layers, all off until the code is entered:
   sweep   Sprachkarte's title-bar shimmer: a soft-light band crosses every 7s,
           entering and leaving off-screen, so the loop restart never shows
   edges   every glass rim turns holo and drifts (windows, dock, icons, widget)
   cards   folio covers wear their holo foil all the time, the sticker gets
           the sweep over a holo face
   trail   pearl glints follow the pointer (js/overlays.js)
   The holo is the Opal accents pushed to pastel: blush, lilac, ice, mint. */
body[data-konami] {
  --holo: linear-gradient(115deg, #f4b8d8 0%, #d3c0ff 22%, #a9d8ff 45%, #c4f1e0 66%, #f6c9e4 84%, #d3c0ff 100%);
  --sweep: linear-gradient(100deg, transparent 35%, #ffffff99 50%, transparent 65%);
  /* the same holo, a step more saturated: pastel on a 2px rim reads as plain white */
  --holo-rim: linear-gradient(115deg, #ff9ccf 0%, #b99bff 22%, #7cc4ff 45%, #8eecc9 66%, #ffa9d9 84%, #b99bff 100%);
}

body[data-konami] .win__bar::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--sweep) no-repeat; background-size: 260% 100%;
  /* Sprachkarte blends it soft-light on mid-tone bars; on night's dark bars that
     vanishes, so screen, which can only lighten */
  mix-blend-mode: screen; opacity: .7; animation: sweep 7s linear infinite;
}
@keyframes sweep { from { background-position: 130% 0; } to { background-position: -130% 0; } }

body[data-konami] .lg::before {
  padding: 2px;
  background:
    radial-gradient(160px 160px at var(--lx, 22%) var(--ly, 0%), #ffffffee, transparent 70%),
    var(--holo-rim);
  background-size: 100% 100%, 300% 100%;
  animation: holo-drift 9s ease-in-out infinite alternate;
}
@keyframes holo-drift { from { background-position: 0 0, 0% 0; } to { background-position: 0 0, 100% 0; } }

/* the cover's foil stays on and drifts by itself; the pointer still adds glare */
body[data-konami] .card__foil {
  opacity: calc(.5 + var(--h, 0) * .25); mix-blend-mode: overlay;
  animation: card-holo 6s ease-in-out infinite alternate;
}
@keyframes card-holo { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
body[data-konami] .card__in { box-shadow: 0 0 0 2px #b99bffaa, 0 0 22px -4px #b99bff88; }

body[data-konami] .sticker {
  background: var(--sweep) no-repeat, var(--holo);
  background-size: 260% 100%, 100% 100%;
  animation: sticker-sweep 7s linear infinite;
}
body[data-konami] .sticker.is-slap { animation: slap .4s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes sticker-sweep { from { background-position: 130% 0, 0 0; } to { background-position: -130% 0, 0 0; } }
/* printed stickers turn holo: the inks shift through the spectrum, white and black stay put */
body[data-konami] .stk { animation: stk-holo 6s linear infinite; }
@keyframes stk-holo { from { filter: hue-rotate(0deg) saturate(1.5); } to { filter: hue-rotate(360deg) saturate(1.5); } }

body[data-konami] .menubar__wm {
  background: var(--holo) 0 0 / 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: holo-text 9s ease-in-out infinite alternate;
}
@keyframes holo-text { to { background-position: 100% 0; } }

.glint {
  position: fixed; z-index: var(--z-toast); pointer-events: none;
  width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  border-radius: 50%; background: var(--c); box-shadow: 0 0 10px var(--c);
  animation: glint 720ms ease-out forwards;
}
.glint--star { width: auto; height: auto; background: none; box-shadow: none; font-size: calc(var(--s) * 2); line-height: 1; color: var(--c); text-shadow: 0 0 8px var(--c); }
@keyframes glint { from { opacity: .95; transform: scale(1); } to { opacity: 0; transform: translate(var(--dx), 14px) scale(.2); } }

.sparkle {
  position: fixed; z-index: var(--z-toast); top: -24px; pointer-events: none;
  font-size: 14px; color: var(--os-accent);
  text-shadow: 0 0 10px color-mix(in srgb, var(--os-accent) 70%, transparent);
  animation: fall linear forwards;
}
@keyframes fall { to { transform: translateY(110vh) rotate(200deg); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  body[data-konami] .win__bar::after, body[data-konami] .lg::before,
  body[data-konami] .sticker, body[data-konami] .stk, body[data-konami] .menubar__wm, body[data-konami] .card__foil { animation: none; }
  .credits__roll { animation-duration: 60s; }
}
