/* snaev.ar
 *
 * Written small-screen first: the base rules are a plain vertical stack of
 * cards, and the fake desktop only switches on above 700px. That way the
 * simplest, most robust layout is also the fallback.
 *
 * Everything visual comes from the custom properties in the theme blocks
 * below, so switching themes is one attribute on <html>.
 */

/* ------------------------------------------------------------------ themes */

/* Text sitting directly on the desktop background rather than inside a window,
   and the one border that has to survive being bent into a circle. Both default
   to their in-window equivalents; a theme overrides them only where the window
   value would be illegible or malformed out there. */
:root {
  --desktop-ink: var(--ink);
  --desktop-accent: var(--accent);
  --border-round: var(--border);
}

:root[data-theme="naive"] {
  --desktop-bg: radial-gradient(#e7ddc8 1.2px, transparent 1.3px) 0 0/22px 22px, #FAF6EE;
  --win: #FFFDF6;
  --ink: #2b2622;
  --border: 2px solid #2b2622;
  --radius: 14px;
  --radius-s: 10px;
  --shadow: 4px 5px 0 rgba(43, 38, 34, .16);
  --title-bg: #FFE3A8;
  --title-ink: #2b2622;
  --accent: #E8747C;
  --link: #4467C4;
  --btn-bg: #fff;
  --font: 'Patrick Hand', cursive;
  --font-display: 'Patrick Hand', cursive;
  --fs: 17px;
}

:root[data-theme="retro"] {
  --desktop-bg: radial-gradient(circle at 50% 25%, #33427a, #131a38 75%);
  --win: linear-gradient(180deg, #3d4d8f, #252e5c);
  --ink: #f0f2ff;
  --border: 2px solid #c7d0ff;
  --radius: 8px;
  --radius-s: 6px;
  --shadow: 0 5px 0 rgba(0, 0, 0, .4);
  --title-bg: linear-gradient(180deg, #5a6cb4, #3a477f);
  --title-ink: #fff;
  --accent: #ffd76a;
  --link: #9fe8ff;
  --btn-bg: rgba(255, 255, 255, .08);
  --font: 'VT323', monospace;
  --font-display: 'VT323', monospace;
  --fs: 20px;
}

:root[data-theme="win95"] {
  --desktop-bg: #008080;
  --win: #c0c0c0;
  --ink: #111;
  --border: 2px outset #dfdfdf;
  --radius: 0px;
  --radius-s: 0px;
  --shadow: 2px 2px 0 rgba(0, 0, 0, .35);
  --title-bg: linear-gradient(90deg, #000080, #1084d0);
  --title-ink: #fff;
  --accent: #000080;
  --link: #0000cc;
  --btn-bg: #c0c0c0;
  --font: Tahoma, 'Segoe UI', sans-serif;
  --font-display: Tahoma, 'Segoe UI', sans-serif;
  --fs: 14px;
  --desktop-ink: #fff;               /* #111 on teal is unreadable */
  --desktop-accent: #ffff80;
  --border-round: 2px solid #6d6d6d; /* `outset` bends into a broken arc */
}

:root[data-theme="synth"] {
  --desktop-bg: linear-gradient(180deg, #170b33 0%, #31135e 60%, #0d0722 100%);
  --win: rgba(23, 10, 45, .93);
  --ink: #f4e9ff;
  --border: 1px solid #ff3cac;
  --radius: 10px;
  --radius-s: 8px;
  --shadow: 0 0 22px rgba(255, 60, 172, .45);
  --title-bg: linear-gradient(90deg, #ff3cac, #784ba0);
  --title-ink: #fff;
  --accent: #00f0d8;
  --link: #00f0d8;
  --btn-bg: rgba(255, 255, 255, .06);
  --font: 'Share Tech Mono', monospace;
  --font-display: 'Orbitron', sans-serif;
  --fs: 15px;
}

/* -------------------------------------------------------------------- base */

*,
*::before,
*::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  padding: 0 0 3rem;
  background: var(--desktop-bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs);
  line-height: 1.45;
}

a { color: var(--link); }
a:hover { color: var(--accent); }

::selection {
  background: var(--accent);
  color: #fff;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ----------------------------------------------------- effect overlays */

/* Both are decoration only and never intercept a pointer. Which ones show is
   decided entirely by the theme attribute — no JavaScript involved. */
.fx {
  display: none;
  position: fixed;
  pointer-events: none;
}

.fx--grid {
  left: 0;
  right: 0;
  bottom: 0;
  height: 36%;
  z-index: 1;
  background:
    repeating-linear-gradient(90deg, rgba(0, 240, 216, .14) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(0deg, rgba(255, 60, 172, .22) 0 1px, transparent 1px 36px);
  border-top: 1px solid rgba(255, 60, 172, .5);
}

.fx--scan {
  inset: 0;
  z-index: 999;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .12) 0 1px, transparent 1px 3px);
}

:root[data-theme="synth"] .fx--grid,
:root[data-theme="retro"] .fx--scan,
:root[data-theme="synth"] .fx--scan { display: block; }

/* ------------------------------------------------------------ mobile topbar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  background: var(--title-bg);
  color: var(--title-ink);
  border-bottom: var(--border);
  font-family: var(--font-display);
}

.topbar__brand { letter-spacing: .4px; }

.topbar__controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ----------------------------------------------------------- desktop icons */

.icons { display: none; }

.icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 0;
  background: none;
  border: none;
  color: var(--desktop-ink);
  text-align: center;
}

.icon__glyph {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  font-size: 22px;
  background: var(--win);
  border: var(--border);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow);
}

.icon__label { font-size: 14px; }

/* ----------------------------------------------------------------- windows */

.windows {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px 12px 0;
}

.win {
  overflow: hidden;
  background: var(--win);
  color: var(--ink);
  border: var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.win[hidden] { display: none; }

.win__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  background: var(--title-bg);
  color: var(--title-ink);
  border-bottom: var(--border);
  font-family: var(--font-display);
  user-select: none;
  touch-action: none;
}

.win__title {
  margin: 0;
  font-size: 1em;
  font-weight: inherit;
  letter-spacing: .4px;
}

.win__close {
  width: 22px;
  height: 22px;
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--btn-bg);
  color: var(--title-ink);
  border: var(--border);
  border-radius: var(--radius-s);
  font-size: 13px;
  line-height: 1;
}

.win__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px 16px;
}

.win__body p { margin: 0; }

@media (max-width: 700px) {
  /* reality.cfg is redundant here: the topbar already holds its controls. */
  .win--themes { display: none; }

  /* On the desktop the grid sits in empty space below the windows. In the
     stacked layout it lands on top of paragraphs, where its horizontal lines
     read as strikethrough. Scanlines alone carry the theme here. */
  :root[data-theme="synth"] .fx--grid { display: none; }

  /* Nothing is closable in the stack, so don't offer a button that does
     nothing — there'd be no icon column to reopen from. */
  .win__close { display: none; }
}

/* ------------------------------------------------------------ window bodies */

.entry {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.entry__note { opacity: .8; }

.about__head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.chibi {
  width: 84px;
  height: 84px;
  flex: none;
  padding: 0;
  overflow: hidden;
  background: var(--btn-bg);
  border: var(--border-round);
  border-radius: 50%;
}

/* Oversized and clipped by the circle rather than scaled: `transform` belongs to
   the pop animation below, and a base scale there would be overwritten.
   Anchored nearer the top so the crop takes the shirt hem, not the hair. */
.chibi__img {
  display: block;
  width: 128%;
  height: 128%;
  margin: -6% 0 0 -14%;
  object-fit: contain;
}

.about__hint {
  margin: 0;
  font-family: monospace;
  font-size: 12px;
  opacity: .75;
  line-height: 1.35;
}

@media (prefers-reduced-motion: no-preference) {
  .chibi__img.is-pop { animation: pop .28s ease-out; }

  @keyframes pop {
    0%   { transform: scale(.72) rotate(-8deg); }
    60%  { transform: scale(1.06) rotate(3deg); }
    100% { transform: scale(1) rotate(0); }
  }
}

/* ----------------------------------------------------------- theme + mute */

.theme-picker {
  display: flex;
  flex: none; /* must not shrink below its buttons and spill them off-screen */
  gap: 10px;
}

.theme-btn {
  width: 46px;
  height: 46px;
  flex: none;
  padding: 0;
  background-color: var(--btn-bg);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  border: var(--border);
  border-radius: var(--radius-s);
}

/* The crayon cat is drawn on transparency, so on the dark themes its outlines
   disappear into --btn-bg. It gets a paper plate of its own instead. The retro
   and synth icons bake their own dark backgrounds in and must not get one. */
.theme-btn[data-theme-key="naive"] { background-color: #FFFDF6; }

.theme-btn[aria-pressed="true"] {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.mute {
  align-self: flex-start;
  flex: none; /* or a narrow topbar shrinks it out of existence */
  padding: 4px 10px;
  background: var(--btn-bg);
  border: var(--border);
  border-radius: var(--radius-s);
}

.mute[data-mute-compact] {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--title-ink);
}

/* Brand + four theme buttons + mute is a tight fit on a 320px phone, so the bar
   shrinks a little. This has to come after the rules above: a media query adds
   no specificity, so on equal specificity it is source order that decides. */
@media (max-width: 420px) {
  .topbar { padding: 8px 10px; }
  .topbar__brand { flex: none; font-size: 15px; }
  .topbar__controls,
  .theme-picker { gap: 6px; }
  .theme-btn { width: 36px; height: 36px; }
  .mute[data-mute-compact] { width: 30px; height: 30px; }
}

/* ------------------------------------------------------------------ footer */

.footer {
  padding: 18px 16px 0;
  color: var(--desktop-ink);
  font-size: 13px;
  opacity: .8;
  font-family: monospace;
  text-align: center;
}

/* The footer sits on the desktop, not in a window, so --link can't be trusted
   to contrast with what's behind it. */
.footer a { color: inherit; }
.footer a:hover { color: var(--desktop-accent); }

/* ================================================================= desktop */

@media (min-width: 701px) {

  html,
  body { height: 100%; }

  body {
    padding: 0;
    overflow: hidden;
  }

  .topbar { display: none; }

  .icons {
    position: absolute;
    left: 18px;
    top: 18px;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 20px;
  }

  .windows {
    display: block;
    padding: 0;
  }

  /* Positions and stacking are set inline by site.js. They are ignored above,
     where .win is statically positioned. */
  .win {
    position: absolute;
    transform: rotate(var(--rot, 0deg));
  }

  .win--about     { width: 350px; --rot: -0.7deg; }
  .win--interests { width: 320px; --rot:  0.6deg; }
  .win--projects  { width: 370px; --rot: -0.4deg; }
  .win--themes    { width: 300px; --rot:  0.8deg; }

  .win__bar { cursor: grab; }
  .win__bar.is-dragging { cursor: grabbing; }

  .footer {
    position: absolute;
    right: 16px;
    bottom: 12px;
    z-index: 2;
    padding: 0;
    text-align: right;
  }
}
