/* fapsec.net — shared site theme
 * Minimal, warm light design. Off-white paper background, near-black ink,
 * a single restrained grey-blue accent. Structure comes from type scale and
 * whitespace rather than boxes and color. System fonts (offline-safe). */

:root {
  --paper:      #f7f4ee;   /* warm off-white background */
  --paper-2:    #efeae1;   /* faint warm panel / hover wash */
  --ink:        #23201b;   /* near-black warm text */
  --ink-soft:   #5c574e;   /* secondary text */
  --ink-faint:  #8a8479;   /* captions / muted */
  --rule:       #ddd6ca;   /* hairline dividers */
  --accent:     #5b7089;   /* grey-blue */

  --space-2: 0.5rem;
  --space-3: 0.85rem;
  --space-4: 1.3rem;
  --space-5: 2.2rem;
  --space-6: 3.5rem;

  --font-body: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-head: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
               "Times New Roman", serif;

  --maxw: 720px;
}

/* fix accent-ink (darker grey-blue for hover) */
:root { --accent-ink: #3f5069; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--rule); transition: color .12s ease, border-color .12s ease; }
a:hover { color: var(--accent-ink); border-bottom-color: var(--accent-ink); }

h1, h2, h3 { font-family: var(--font-head); color: var(--ink); font-weight: 600; line-height: 1.15; margin: 0 0 var(--space-3) 0; letter-spacing: -0.01em; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--space-4); }

/* ---- Header ---- */
.site-header { padding: var(--space-6) 0 var(--space-5); }
.site-header .eyebrow { color: var(--accent); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.72rem; }
.site-header h1 { font-size: clamp(2rem, 5vw, 2.8rem); margin: var(--space-2) 0 var(--space-3); }
.site-header .tagline { color: var(--ink-soft); font-size: 1.08rem; max-width: 48ch; margin: 0; }

/* ---- Two-column front door: identity (left) | talks (right) ---- */
.split { display: grid; grid-template-columns: 320px 1fr; gap: var(--space-6); padding: var(--space-6) 0; align-items: start; }
.split .identity { position: sticky; top: var(--space-5); }
.split .identity .eyebrow { color: var(--accent); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.72rem; }
.split .identity h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: var(--space-2) 0 var(--space-2); }
.split .identity .byline { color: var(--ink-soft); font-size: 1.02rem; margin: 0 0 var(--space-4); }
/* vertical divider between the columns */
.split .talks { border-left: 1px solid var(--rule); padding-left: var(--space-6); min-width: 0; }
.split .talks .section-title { margin-top: 0; }

/* ---- Glitch portrait ----
   A real photo with an occasional RGB-split flicker, done entirely in CSS so
   it stays sharp, light, and offline. Three stacked copies: a clean base and
   two channel-tinted overlays that sit dormant and dead-aligned most of the
   cycle, then briefly offset + slice for a fraction of a second. */
.glitch {
  position: relative;
  width: 100%;
  aspect-ratio: 753 / 1000;
  margin-top: var(--space-4);
  overflow: hidden;
  border-radius: var(--radius-sm, 0.4rem);
  border: 1px solid var(--rule);
  background: var(--paper-2);
  filter: saturate(1.0) contrast(1.12);
}
.glitch .layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* base image stays put */
.glitch .base { z-index: 1; }
/* Block glitch overlays: copies of the photo that stay invisible, then flash a
   small RECTANGULAR region (clip-path inset bounded on all four sides) at a
   random-feeling spot, nudged + channel-tinted so it reads as a corrupted
   block. Several layers fire on staggered beats across a short loop so the
   glitch appears frequently. */
.glitch .chan {
  z-index: 2;
  mix-blend-mode: screen;
  opacity: 0;
  will-change: transform, clip-path, opacity;
}
/* red/cyan channel tints for the split look. Position/opacity are driven by
   JS (see index.html) so the blocks are randomized and never repeat. */
.glitch .b1 { filter: sepia(1) saturate(9) hue-rotate(-40deg) contrast(1.3); }
.glitch .b2 { filter: sepia(1) saturate(9) hue-rotate(140deg) contrast(1.3); }
.glitch .b3 { filter: sepia(1) saturate(8) hue-rotate(-40deg) contrast(1.3); }
/* a thin scanline flash, pulsed by JS on block beats */
.glitch .scan {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(rgba(255,255,255,0.08), rgba(0,0,0,0.06));
  mix-blend-mode: overlay; opacity: 0;
}

/* ---- VHS layers combined over the block glitch ----
   Settings from tuning: static 26, scanline strength 22/40, roll speed 38. */
/* animated static/grain (painted by a tiny JS noise loop) */
.glitch .vhs-static {
  position: absolute; inset: 0; z-index: 4; width: 100%; height: 100%;
  mix-blend-mode: screen; opacity: 0.26; pointer-events: none;
}
/* fine VHS scanlines */
.glitch .vhs-lines {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  opacity: 0.55;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0) 0px, rgba(0,0,0,0) 2px,
    rgba(0,0,0,0.18) 3px, rgba(0,0,0,0.18) 4px);
}
/* rolling tracking band drifting down the frame */
.glitch .vhs-track {
  position: absolute; left: 0; right: 0; height: 14%; z-index: 6; pointer-events: none;
  background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0.14), rgba(255,255,255,0));
  filter: blur(1px);
  animation: vhs-roll 8.2s linear infinite;
}
/* constant subtle chromatic fringe on the base for tape feel */
.glitch .base { filter: drop-shadow(1.5px 0 0 rgba(255,0,60,0.28)) drop-shadow(-1.5px 0 0 rgba(0,200,255,0.28)); }

@keyframes vhs-roll { 0% { top: -16%; } 100% { top: 100%; } }


/* Respect users who prefer no motion: show the clean photo, no flicker. */
@media (prefers-reduced-motion: reduce) {
  .glitch .chan, .glitch .scan { animation: none; opacity: 0; }
  .glitch .vhs-static { opacity: 0; }
  .glitch .vhs-track { animation: none; display: none; }
  .glitch .base { animation: none; }
}

/* ---- Social / link row ---- */
.links-row { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-4); }
.links-row a { font-size: 0.92rem; color: var(--ink-soft); border-bottom-color: transparent; }
.links-row a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---- Section heading ---- */
.section-title { font-family: var(--font-head); font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-faint); margin: var(--space-6) 0 var(--space-3); padding-bottom: var(--space-2); border-bottom: 1px solid var(--rule); }

/* ---- Talks as a typographic list ---- */
.talk-list { list-style: none; margin: 0; padding: 0; }
.talk-list > li { padding: var(--space-4) 0; border-bottom: 1px solid var(--rule); }
.talk-list > li:last-child { border-bottom: none; }
.talk-list .talk-title { display: block; font-family: var(--font-head); font-size: 1.4rem; font-weight: 600; color: var(--ink); border-bottom: none; }
.talk-list a.talk-title:hover { color: var(--accent-ink); }
.talk-list .talk-kicker { display: block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent); margin-bottom: 0.25em; }
.talk-list .talk-desc { color: var(--ink-soft); font-size: 1rem; margin: 0.35em 0 0; }
.talk-list .talk-more { display: inline-block; margin-top: 0.5em; font-size: 0.9rem; color: var(--accent); border-bottom: none; }
.talk-list .talk-more:hover { color: var(--accent-ink); }

/* ---- Versions table (minimal: hairlines only) ---- */
.table-wrap { margin-top: var(--space-4); overflow-x: auto; }
table.versions { width: 100%; border-collapse: collapse; }
table.versions th, table.versions td { text-align: left; padding: 0.65em 1em 0.65em 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
table.versions thead th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-faint); font-weight: 700; }
table.versions tbody tr:last-child td { border-bottom: none; }
table.versions .ver { font-family: var(--font-head); font-weight: 600; color: var(--ink); white-space: nowrap; }
table.versions .latest { display: inline-block; margin-left: 0.4em; font-size: 0.58rem; color: var(--paper); background: var(--accent); padding: 0.12em 0.5em; border-radius: 3px; letter-spacing: 0.05em; text-transform: uppercase; vertical-align: middle; }
.muted { color: var(--ink-faint); }
.todo { color: var(--accent-ink); font-style: italic; }

/* ---- Back link ---- */
.backlink { display: inline-block; margin-top: var(--space-5); color: var(--ink-faint); font-size: 0.9rem; border-bottom-color: transparent; }
.backlink:hover { color: var(--accent); }

/* ---- Footer ---- */
.site-footer { margin-top: var(--space-6); padding: var(--space-5) 0 var(--space-6); border-top: 1px solid var(--rule); color: var(--ink-faint); font-size: 0.82rem; }
.site-footer .disclaimer { max-width: 60ch; margin: 0 0 var(--space-2); }

@media (max-width: 600px) {
  body { font-size: 16px; }
}

/* Split layout: needs a wider frame than the reading pages, and collapses
   to a single column (divider moves to the top of the talks) on narrow screens. */
.wrap.wide { max-width: 980px; }
@media (max-width: 720px) {
  .split { grid-template-columns: 1fr; gap: var(--space-4); }
  .split .identity { position: static; }
  .split .talks { border-left: none; border-top: 1px solid var(--rule); padding-left: 0; padding-top: var(--space-4); }
}
