/* ── Night ────────────────────────────────────────────────────────────────
 *
 * Loaded after style.css and inert until <html data-theme="night"> is set.
 * Only the deltas live here: ~60 declarations against the day build's 1045
 * lines, so the two themes cannot drift apart the way two copies of a
 * stylesheet always do.
 *
 * The rule for reading this file: the day build is a black-ink page on
 * parchment, and most of its art is white-on-transparent art inverted into
 * ink. Night does not invert it. That is why so much of what follows is
 * `filter: none` rather than a colour — the assets were always built for a
 * dark page, and the day build is the one doing the work.
 *
 * Every selector is prefixed with html[data-theme="night"], which outranks
 * anything in style.css including its id rules, so nothing here needs
 * !important.
 */

/* The white at the very top and bottom on a phone is the user agent's canvas,
   not anything this page drew: the body's layers are `fixed` and so paint only
   the viewport, leaving the rubber-band overscroll area above and below the
   document to fall through to the default white. color-scheme hands the UA a
   dark canvas (and dark scrollbars), and the background-color guarantees the
   paint even where the fixed layers do not reach. */
html[data-theme="night"] {
  color-scheme: dark;
  background-color: #05060a;

  --bg:      #08090c;
  --surface: #14161c;
  --border:  rgba(198, 186, 158, 0.15);
  --text:    #d9d4c7;
  --dim:     #a29b8b;
  --muted:   #7b7566;
  --accent:  #e8dec2;
  --prompt:  #9aa6b4;
  --gold:    #9aa6b4;
  --gold-hi: #eef3f9;

  /* read by eye3d.js and the wisps: see style.css for the day values */
  --particle-ink: #e8e1d1;
  --wisp-ember:   rgba(154, 166, 180, 0.20);
  --wisp-ash:     rgba(216, 210, 192, 0.06);
  /* three times the day build's erase: the same tail that reads as smoke on
     parchment piles up into a scribbled mesh on black */
  --wisp-fade:    0.20;

  scrollbar-color: #2c2f38 var(--bg);
}

/* Moon behind cloud: a small cold bloom high up, everything falling to soot
   at the edges. There was a warm candlelight layer under this, and it tinted
   the lower half of every page brown — on a page whose only warm colour is
   the gold accent that read as a stain rather than as a second light source.
   Gold now has the warmth to itself. */
html[data-theme="night"] body {
  background:
    radial-gradient(ellipse 46% 34% at 50% 10%, rgba(150, 168, 196, 0.20) 0%, transparent 70%),
    radial-gradient(ellipse 120% 90% at 50% 12%, #131720 0%, #0a0c11 45%, #05060a 100%);
  /* Every layer, not just the last one. `fixed` at the end of the shorthand
     applies to the final layer only, so the moon bloom defaulted to `scroll` —
     and a scrolling layer is positioned against a body that is height:100%,
     i.e. one viewport tall, then repeated. That tiled the bloom every
     viewport-height down the page and drew a hard seam at each join, worst on
     a phone where the document is five screens tall. */
  background-attachment: fixed;
  background-repeat: no-repeat;
}

html[data-theme="night"] ::selection {
  background: rgba(154, 166, 180, 0.32);
}

html[data-theme="night"]::-webkit-scrollbar-thumb {
  background: #2c2f38;
}

html[data-theme="night"]::-webkit-scrollbar-thumb:hover {
  background: #454a57;
}

html[data-theme="night"] #statusbar,
html[data-theme="night"] .site-nav {
  background: linear-gradient(180deg, rgba(13, 15, 20, 0.94), rgba(6, 7, 11, 0.9));
}

html[data-theme="night"] #sudo-toast {
  color: #d4574c;
  border-color: rgba(212, 87, 76, 0.35);
}

/* The room falls off to nothing at the edges. Heavier than the day build
   because black has further to fall than parchment does. */
html[data-theme="night"] body::after {
  background:
    radial-gradient(ellipse at 50% 30%, transparent 42%, rgba(0, 0, 0, 0.55) 100%);
}

html[data-theme="night"] #boot {
  color: #8a8271;
}

/* No filter swap on the flight out. The day build inverts the emblem as it
   leaves the black boot screen for a parchment page; at night the page it
   lands on is the same darkness it took off from, so the art is left alone
   at every stage of the flight. */
html[data-theme="night"] #avatar-wrap.boot-pose #eye-icon,
html[data-theme="night"] #avatar-wrap.boot-pose #avatar,
html[data-theme="night"] #avatar-wrap.boot-pose canvas,
html[data-theme="night"] #avatar-wrap.boot-pose.flying #eye-icon,
html[data-theme="night"] #avatar-wrap.boot-pose.flying #avatar,
html[data-theme="night"] #avatar-wrap.boot-pose.flying canvas,
html[data-theme="night"] .nav-brand img,
html[data-theme="night"] #eye-icon,
html[data-theme="night"] #avatar,
html[data-theme="night"] .social-link img {
  /* white-on-transparent art needs no inversion on a black page */
  filter: none;
}

html[data-theme="night"] .section::before {
  background: linear-gradient(90deg, var(--gold), var(--gold-hi) 45%, rgba(154, 166, 180, 0));
}

/* Moonlight through tracery rather than god rays: narrower, colder, and far
   dimmer. Light entering a dark room reads by contrast, so at the day
   build's 0.4 it looked like a lens flare instead of a window. */
html[data-theme="night"] #hero::before {
  background: repeating-conic-gradient(from 195deg at 260px 160px,
    rgba(206, 220, 244, 0.085) 0deg 3deg,
    transparent 3deg 19deg);
}

/* The blade is black ink, so here it is inverted to lit stone and held low:
   a silhouette catching the moon, not an object. */
html[data-theme="night"] #hero-sword {
  opacity: 0.3;
  filter: invert(1) sepia(0.3) saturate(0.55) brightness(0.92);
}

html[data-theme="night"] #avatar-wrap:hover {
  filter: drop-shadow(0 0 14px rgba(154, 166, 180, 0.55));
}

html[data-theme="night"] .tech-grid i::after {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.7);
}

/* A six-winged seraph rather than a rotated square. It is a mask, so the
   colour still comes from the page and the hover state stays the same
   one-property change the diamond used. Bone, not the dim stone: at this
   size the wings are mostly negative space, and a mid-grey silhouette on
   near-black loses the blades entirely. */
html[data-theme="night"] .tl-dot {
  width: 15px;
  height: 15px;
  margin-top: 2px;
  margin-left: -2.5px;  /* keep the spine on the timeline rule, not the box */
  border: none;
  transform: none;
  background: var(--text);
  -webkit-mask: url("pics/seraph.svg") center / contain no-repeat;
  mask: url("pics/seraph.svg") center / contain no-repeat;
  transition: background 0.25s ease, filter 0.25s ease;
}

/* drop-shadow, not box-shadow: a box glow is painted on the element box and
   the mask cuts it straight back off again */
html[data-theme="night"] .tl-item:hover .tl-dot {
  background: var(--gold);
  box-shadow: none;
  filter: drop-shadow(0 0 5px rgba(154, 166, 180, 0.75));
}

/* Chips: the day build bevels them light-on-top, which is a raised edge lit
   from above. Same logic, inverted materials. */
html[data-theme="night"] .tl-demo,
html[data-theme="night"] .tl-tags span,
html[data-theme="night"] .proj-tags span {
  border-color: rgba(198, 186, 158, 0.16);
  border-top-color: rgba(255, 248, 226, 0.14);
  border-bottom-color: rgba(0, 0, 0, 0.65);
  background: linear-gradient(180deg, #1d2027, #101218);
}

html[data-theme="night"] .tl-demo:hover {
  border-color: rgba(154, 166, 180, 0.5);
}

html[data-theme="night"] .tl-item:hover .tl-tags span {
  border-color: rgba(154, 166, 180, 0.55);
}

html[data-theme="night"] .tl-body li {
  color: #b5ae9d;
}

html[data-theme="night"] .glow-card::after {
  background: conic-gradient(
    from calc(var(--start, 0) * 1deg) at var(--x, 50%) var(--y, 50%),
    transparent 0deg,
    rgba(154, 166, 180, 0.15) 20deg,
    rgba(154, 166, 180, 0.95) 55deg,
    rgba(238, 243, 249, 1) 80deg,
    rgba(78, 87, 101, 0.9) 105deg,
    rgba(154, 166, 180, 0.3) 135deg,
    transparent 160deg,
    transparent 360deg
  );
}

/* Smoked glass instead of frosted: darker than the page it sits on, with one
   lit top edge, so a grid reads as recessed panels rather than floating
   tiles. The wings are inset rather than bled off the edges, so the panel has a
   margin and the tips resolve inside the frame instead of being cut by it.
   Their opacity is baked into the PNG's alpha, since a background layer
   cannot carry its own. */
html[data-theme="night"] .project-card {
  background:
    url("pics/projects/wings.png") center 45% / 90% auto no-repeat,
    linear-gradient(150deg, rgba(28, 31, 39, 0.72) 0%, rgba(8, 9, 13, 0.55) 100%);
  border-color: rgba(198, 186, 158, 0.13);
  box-shadow: inset 0 1px 0 rgba(255, 246, 220, 0.09);
}

/* No backdrop blur at night. The grid sets perspective and every card gets a
   translateZ on mousemove, so each blurred backdrop becomes its own composited
   layer — and Chrome renders those layers' edges as hard rectangular seams in
   the page background, on card boundaries. It also bought nothing: the day
   build blurs a light gradient to get frosted glass, where here the backdrop
   is a near-black gradient and blurring it is invisible work. */
html[data-theme="night"] .project-card {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

html[data-theme="night"] .project-mark {
  --mark-ink: #9aa6b4;
  /* a lit reliquary window, not a paper roundel: warm centre, gold rim,
     black beyond it */
  background:
    radial-gradient(circle at 50% 50%,
      rgba(18, 21, 28, 0.95) 0 22%,
      rgba(154, 166, 180, 0.45) 23% 24%,
      transparent 25%);
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.75));
}

/* The wings on the card are the card's ornament; the day build's blade
   underneath the diamond only fought them. */
html[data-theme="night"] .project-mark::before {
  display: none;
}

html[data-theme="night"] .project-mark::after {
  border-color: rgba(154, 166, 180, 0.45);
  background: linear-gradient(135deg, rgba(30, 35, 46, 0.85), rgba(10, 11, 16, 0.6));
  box-shadow:
    0 0 0 4px rgba(0, 0, 0, 0.45),
    0 0 22px rgba(154, 166, 180, 0.22);
}

/* The night sigils are drawn in candle gold in the files themselves, so
   nothing here recolours them — the day build's filter turns black stock
   glyphs into ink, and a filter cannot express "this line heavier than that
   one", which is most of what makes the night set read as one hand. The
   brand mark is drawn to the same rules as the rest, so it loses its
   exemption from the page's colour and its larger size. */
html[data-theme="night"] .project-mark img,
html[data-theme="night"] .project-mark-brand img {
  width: 38%;
  height: 38%;
  opacity: 0.92;
  filter: none;
}

html[data-theme="night"] .project-overlay {
  background: rgba(5, 6, 10, 0.82);
}

/* gilt catching a passing light, not a white flash: on black the day build's
   0.85 white blew the whole card out for a frame */
html[data-theme="night"] .project-card::before {
  background: linear-gradient(115deg,
    transparent 32%, rgba(238, 243, 249, 0.14) 48%, transparent 62%);
}

html[data-theme="night"] .project-card:hover .proj-cta,
html[data-theme="night"] .project-card.touch-open .proj-cta {
  text-shadow: 0 0 12px rgba(154, 166, 180, 0.6);
}

/* ── The control ──────────────────────────────────────────────────────────
 * Lives in style.css's nav, so it is styled here once and inherits the
 * theme's own tokens in both directions.
 */
#theme-toggle {
  position: absolute;
  right: 14px;
  top: 50%;
  translate: 0 -50%;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  font-family: inherit;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0;
  clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 5px 100%, 0 calc(100% - 5px));
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

#theme-toggle:hover {
  color: var(--accent);
  border-color: var(--gold);
}

#theme-toggle .glyph {
  font-size: 11px;
  line-height: 1;
  color: var(--prompt);
}

/* the label names where you are going, not where you are */
@media (max-width: 580px) {
  #theme-toggle .label { display: none; }
  #theme-toggle { padding: 3px 6px; }
}
