/* ============================================================
   PSK content templates — shared styles

   Ported from prabhashankar-personal-website@main src/styles/theme.css.
   Tokens live in tokens.css; everything here is built from them.
   ============================================================ */
@import url('tokens.css');

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--psk-font-sans);
  color: var(--psk-fg-1);
  background: #101820;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------- Canvas ---------- */
.psk-canvas {
  background: var(--psk-bg);
  color: var(--psk-fg-1);
  position: relative;
  overflow: hidden;
  font-family: var(--psk-font-sans);
}
.psk-carousel, .psk-single { width: 1080px; height: 1350px; }
.psk-a4 { width: 794px; height: 1123px; }

/* ---------- The two fixed layers ----------
   A 60px grid under the content and film grain above it. Both are on the
   site and both are what make a page read as this brand rather than as a
   generic light layout.

   Layer order on a canvas, bottom to top:

     0   the grid
     1   the photo, when a template sets one
     2   the photo's flat overlay
     3   .psk-content, every renderer's output
     60  the grain

   The grid used to sit at 2, above the photo and above any content that was
   not wrapped in a positioned layer. Plain flow content paints below a
   positioned z-index:0 element, so on every template without a photo the
   grid ruled straight across the copy. The grid is the bottom layer now and
   template.html wraps all renderer output in .psk-content, so content clears
   it whether or not there is a photo. */
.psk-canvas::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none; opacity: 0.55;
  background-image:
    linear-gradient(to right, var(--psk-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--psk-grid-line) 1px, transparent 1px);
  background-size: 60px 60px;
}
[data-theme="dark"] .psk-canvas::before { opacity: 0.4; }

.psk-canvas::after {
  content: '';
  position: absolute; inset: 0; z-index: 60;
  pointer-events: none; opacity: 0.022;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* A full-bleed photo already carries its own texture, and the grid read as
   damage on top of one, which is why this used to drop the grid to 0.18
   opacity. The grid is beneath the photo now, so the photo covers it and
   the fudge is not needed. The class is kept because index.html sets it. */
.psk-canvas.has-photo::before { opacity: 0.55; }

/* Every renderer's output is mounted inside one of these. It is a positioned
   layer above the grid, and it is the containing block for the absolutely
   positioned pieces the renderers use, so `inset: 0` in a renderer still
   means the full canvas. */
.psk-content { position: absolute; inset: 0; z-index: 3; }

/* A4 continuation pages. The cover carries the masthead; every page after it
   gets this running head at the top and .psk-page-num at the foot. */
.psk-running-head {
  position: absolute;
  top: 44px; left: 64px; right: 64px;
  display: flex; justify-content: space-between;
  font-family: var(--psk-font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--psk-fg-2);
  padding-bottom: 16px;
  border-bottom: 1px solid var(--psk-card-border);
}

/* ============================================================
   Legacy overrides.

   The renderers were written against the old system and carry roughly 55
   hardcoded border radii and 199 hardcoded font weights as inline styles.
   Inline styles beat a stylesheet, so these have to be forced. Without them
   the templates come out as the new palette wearing the old shapes, which is
   worse than either system on its own.
   ============================================================ */

/* Square corners. The old kit used 9999px pills and 12 to 32px cards. */
.psk-canvas *:not(.psk-dot):not(.psk-avatar) { border-radius: 0 !important; }

/* Bebas Neue is a single weight and caps only. Headings asking for 700 would
   otherwise get a synthesised bold, and the -0.04em tracking the old sans
   needed makes Bebas collide with itself. */
.psk-canvas h1,
.psk-canvas h2,
.psk-canvas h3,
.psk-canvas .psk-display {
  font-family: var(--psk-font-display) !important;
  font-weight: 400 !important;
  letter-spacing: 0.005em !important;
  text-transform: uppercase;
  line-height: 0.92;
}

/* Everything that is not a heading is mono, and mono has no bold in this
   system: emphasis comes from the 500 weight and from colour.

   This inherits from .psk-canvas rather than listing element selectors. An
   earlier version set `.psk-canvas div { font-family: ... }`, which at (0,1,1)
   outranked single-class display rules like .sig-quote and .sig-stat and
   quietly dragged them back to mono. Inheritance costs no specificity, so the
   sig-* classes win as intended. */
.psk-canvas *:not(h1):not(h2):not(h3):not(.psk-display) { font-weight: inherit; }
.psk-canvas [style*="font-weight: 700"],
.psk-canvas [style*="fontWeight:700"] { font-weight: 500 !important; }

/* Mono sizes floor at 13px on the site. Nothing smaller ships here either. */
.psk-canvas { font-size: 15px; }

/* ---------- Eyebrow ----------
   The site's eyebrow is a bare uppercase mono label with wide tracking. The
   old kit gave it a tinted pill; that pill is gone. */
.psk-eyebrow {
  display: inline-block;
  font-family: var(--psk-font-mono);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--psk-brand-text);
  background: transparent;
  padding: 0;
}

.psk-pill {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 18px;
  border: 1px solid var(--psk-card-border);
  background: transparent;
  color: var(--psk-brand-text);
  font-family: var(--psk-font-mono);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------- Wordmark ----------
   On the site the name is set in mono, not in the display face. */
.psk-wordmark {
  font-family: var(--psk-font-mono);
  font-weight: 500;
  letter-spacing: 0.02em;
  font-size: 26px;
  color: var(--psk-fg-1);
  text-transform: uppercase;
}
.psk-wordmark .dot { color: var(--psk-brand); }

.psk-brand-text { color: var(--psk-brand-text); }
.psk-fade-text  { color: var(--psk-fg-1); }

/* ---------- Footer band ---------- */
.psk-footer-band {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 24px 60px;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--psk-font-mono);
  font-size: 15px;
  color: var(--psk-fg-2);
  border-top: 1px solid var(--psk-card-border);
  z-index: 4;
}

.psk-page-num {
  position: absolute;
  bottom: 40px; right: 60px;
  font-family: var(--psk-font-mono);
  font-size: 15px;
  color: var(--psk-fg-2);
  letter-spacing: 0.12em;
  z-index: 4;
}

/* ============================================================
   Signal components. These are the parts of the new site language that had
   no equivalent in the old kit, used by the templates in data-signal.js.
   ============================================================ */

/* The fixed dot rail. On the site it runs down the left edge as section
   navigation; on a slide it reads as a position marker. */
.sig-rail {
  position: absolute; top: 0; bottom: 0; left: 0; width: 80px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  border-right: 1px solid var(--psk-card-border);
  z-index: 4;
}
.sig-rail .psk-dot {
  width: 9px; height: 9px; border-radius: 9999px !important;
  background: var(--psk-fg-3); opacity: 0.5;
}
.sig-rail .psk-dot.is-on { background: var(--psk-brand); opacity: 1; height: 30px; border-radius: 0 !important; }

/* Left-anchored full-bleed body, cleared of the rail. */
.sig-body {
  position: absolute; inset: 0;
  padding: 96px 88px 96px 152px;
  display: flex; flex-direction: column;
  z-index: 4;
}
.sig-body.no-rail { padding-left: 88px; }

.sig-kicker {
  font-family: var(--psk-font-mono); font-size: 17px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.22em; color: var(--psk-brand-text);
}
.sig-micro {
  font-family: var(--psk-font-mono); font-size: 16px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--psk-fg-2);
}
.sig-h {
  font-family: var(--psk-font-display); font-weight: 400;
  font-size: 132px; line-height: 0.88; letter-spacing: 0.005em;
  text-transform: uppercase; color: var(--psk-fg-1); margin: 0;
}
.sig-h.sm { font-size: 92px; }
.sig-h.xs { font-size: 68px; }
.sig-h em { font-style: normal; color: var(--psk-brand); }
.sig-lede { font-size: 27px; line-height: 1.5; color: var(--psk-fg-2); margin: 0; }
.sig-body-copy { font-size: 23px; line-height: 1.55; color: var(--psk-fg-2); margin: 0; }

/* Terminal-style rule with a label sitting on it. */
.sig-rule { display: flex; align-items: center; gap: 20px; }
.sig-rule::after { content: ''; flex: 1; height: 1px; background: var(--psk-card-border); }

/* Numbered rows, the site's index pattern. */
.sig-row { display: flex; gap: 32px; align-items: baseline; padding: 26px 0; border-bottom: 1px solid var(--psk-card-border); }
.sig-row:last-child { border-bottom: 0; }
.sig-row .n { font-family: var(--psk-font-mono); font-size: 17px; font-weight: 500; color: var(--psk-brand-text); letter-spacing: 0.12em; min-width: 62px; }
.sig-row .t { font-family: var(--psk-font-display); font-size: 46px; line-height: 1; text-transform: uppercase; color: var(--psk-fg-1); }
.sig-row .b { font-size: 21px; line-height: 1.5; color: var(--psk-fg-2); margin-top: 10px; }

/* Key/value spec block. */
.sig-spec { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; padding: 22px 0; border-bottom: 1px solid var(--psk-card-border); }
.sig-spec:last-child { border-bottom: 0; }
.sig-spec .k { font-family: var(--psk-font-mono); font-size: 16px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.16em; color: var(--psk-fg-3); }
.sig-spec .v { font-family: var(--psk-font-display); font-size: 36px; text-transform: uppercase; color: var(--psk-fg-1); text-align: right; line-height: 1; }

/* Big numeral. */
.sig-stat { font-family: var(--psk-font-display); font-size: 300px; line-height: 0.8; color: var(--psk-brand); text-transform: uppercase; }
.sig-stat.md { font-size: 200px; }
.sig-stat.sm { font-size: 140px; }

/* Bordered panel. Square, hairline, no shadow. */
.sig-card { border: 1px solid var(--psk-card-border); background: var(--psk-card-bg); padding: 34px; }
.sig-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.sig-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

/* Photo box. */
.sig-photo { position: relative; overflow: hidden; background: var(--psk-bg-alt); background-size: cover; background-position: center; }
.sig-photo::after { content: ''; position: absolute; inset: 0; background: rgba(5,18,41,0.12); }
.sig-photo .cap { position: absolute; left: 16px; bottom: 16px; z-index: 2; background: var(--psk-prussian, #051229); color: #fff;
  font-family: var(--psk-font-mono); font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase; padding: 8px 14px; }

.sig-quote { font-family: var(--psk-font-display); font-size: 74px; line-height: 0.98; text-transform: uppercase; color: var(--psk-fg-1); }
.sig-by { font-family: var(--psk-font-mono); font-size: 17px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--psk-fg-3); }

.sig-cta {
  display: inline-flex; align-items: center; gap: 14px;
  background: var(--psk-brand); color: #fff;
  font-family: var(--psk-font-mono); font-weight: 500; font-size: 21px;
  letter-spacing: 0.08em; text-transform: uppercase; padding: 20px 32px;
  align-self: flex-start;
}
.sig-cta.ghost { background: transparent; color: var(--psk-fg-1); border: 1px solid var(--psk-fg-1); }

.no-print { }

/* ---------- Signal grounds ----------
   A toned slide paints its own ground and its own grid, because the canvas
   grid is a pseudo-element of .psk-canvas and a renderer cannot reach it to
   change the line colour. When a ground layer is present the canvas grid steps
   aside and the ground's own grid takes over. */
.psk-canvas:has(.sig-ground)::before { opacity: 0; }

.sig-ground {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--sig-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--sig-line) 1px, transparent 1px);
  background-size: 60px 60px;
}
/* The fill sits under the grid on the same layer. */
.sig-ground::before { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--sig-fill); }

.sig-ground--blue  { --sig-fill: var(--crayola-blue);  --sig-line: rgba(255,255,255,0.18); }
.sig-ground--deep  { --sig-fill: var(--prussian-blue); --sig-line: #0d2242; }
.sig-ground--panel { --sig-fill: var(--psk-bg-alt);    --sig-line: rgba(5,18,41,0.07); }

/* Token overrides for the content that sits on a toned ground. Set on the
   content wrapper so they cascade to every child, which is what the earlier
   sibling-div approach could not do. */
.sig-tone-blue {
  --psk-fg-1: #ffffff; --psk-fg-2: rgba(255,255,255,0.88); --psk-fg-3: rgba(255,255,255,0.72);
  --psk-brand: #ffffff; --psk-brand-text: #ffffff;
  --psk-card-border: rgba(255,255,255,0.34); --psk-card-bg: rgba(255,255,255,0.10);
}
.sig-tone-deep {
  --psk-fg-1: #f2f5f9; --psk-fg-2: #9aa8bb; --psk-fg-3: #6f7d90;
  --psk-brand-text: #64aaff;
  --psk-card-border: #1c3153; --psk-card-bg: #0a1a33;
}

/* ============================================================
   Signal design frames.

   The first pass built all fourteen designs from one body layout and varied
   only the ground and the anchor, so they read as one design in fourteen
   colours. Each now has its own composition.
   ============================================================ */

/* 02 index: a contents column on the leading edge, content beside it. */
.sig-idx { position: absolute; inset: 96px auto 96px 88px; width: 190px; z-index: 4;
  display: flex; flex-direction: column; gap: 14px; border-right: 1px solid var(--psk-card-border); padding-right: 26px; }
.sig-idx .ix { font-family: var(--psk-font-mono); font-size: 16px; letter-spacing: 0.16em; color: var(--psk-fg-3); }
.sig-idx .ix.on { color: var(--psk-brand); font-weight: 500; }
.sig-body.with-idx { padding-left: 330px; }

/* 03 spec sheet: content inside a hairline box, not on the bare ground. */
.sig-boxed { position: absolute; inset: 132px 88px 132px 88px; z-index: 4;
  border: 1px solid var(--psk-card-border); background: var(--psk-card-bg);
  padding: 56px; display: flex; flex-direction: column; justify-content: center; }

/* 04 numeral: the slide number as an oversized watermark bleeding off. */
.sig-watermark { position: absolute; left: -40px; bottom: -70px; z-index: 2;
  font-family: var(--psk-font-display); font-size: 460px; line-height: 0.7;
  color: var(--psk-brand); opacity: 0.1; pointer-events: none; }

/* 05 terminal: a window frame around the content. */
.sig-term { position: absolute; inset: 120px 88px 130px 88px; z-index: 4;
  border: 1px solid var(--psk-card-border); background: var(--psk-card-bg); display: flex; flex-direction: column; }
.sig-term .tbar { display: flex; align-items: center; gap: 10px; padding: 18px 22px; border-bottom: 1px solid var(--psk-card-border); }
.sig-term .tbar i { width: 11px; height: 11px; border-radius: 9999px !important; background: var(--psk-fg-3); opacity: 0.55; }
.sig-term .tbar .path { margin-left: 12px; font-family: var(--psk-font-mono); font-size: 15px; letter-spacing: 0.1em; color: var(--psk-fg-3); }
.sig-term .tbody { flex: 1; padding: 44px; display: flex; flex-direction: column; justify-content: center; }

/* 07 deep: content centred between two full-width rules. */
.sig-between { border-top: 1px solid var(--psk-card-border); border-bottom: 1px solid var(--psk-card-border); padding: 56px 0; }

/* 09 compare: a hairline down the centre of the slide. */
.sig-divider { position: absolute; top: 150px; bottom: 150px; left: 50%; width: 1px; background: var(--psk-card-border); z-index: 3; }

/* 10 phases: a step track along the foot. */
.sig-track { display: flex; gap: 0; align-items: stretch; border-top: 1px solid var(--psk-card-border); }
.sig-track .st { flex: 1; padding: 26px 22px 0 0; position: relative; }
.sig-track .st::before { content: ''; position: absolute; top: -5px; left: 0; width: 9px; height: 9px; background: var(--psk-brand); }
.sig-track .st .d { font-family: var(--psk-font-mono); font-size: 15px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--psk-brand-text); }
.sig-track .st .t { font-family: var(--psk-font-display); font-size: 34px; text-transform: uppercase; line-height: 1; margin-top: 10px; color: var(--psk-fg-1); }
.sig-track .st .b { font-size: 18px; line-height: 1.45; color: var(--psk-fg-2); margin-top: 8px; }

/* 11 checklist: oversized marks. */
.sig-bigcheck { display: flex; gap: 26px; align-items: flex-start; padding: 22px 0; }
.sig-bigcheck .mk { width: 40px; height: 40px; border: 2px solid var(--psk-brand); color: var(--psk-brand);
  display: flex; align-items: center; justify-content: center; font-size: 22px; flex: 0 0 auto; }
.sig-bigcheck .tx { font-size: 26px; line-height: 1.4; color: var(--psk-fg-2); padding-top: 4px; }

/* 12 statement: type edge to edge, chrome reduced to the counter. */
.sig-edge { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column;
  justify-content: center; padding: 0 72px; }
.sig-edge .sig-h { font-size: 168px; line-height: 0.86; }

/* 13 quote: a display-scale quote mark bleeding off the leading edge. */
.sig-qmark { position: absolute; top: 130px; left: 40px; z-index: 3;
  font-family: var(--psk-font-display); font-size: 300px; line-height: 0.6; color: var(--psk-brand); opacity: 0.22; }

/* 14 closer: a full-bleed accent bar carrying the call to action. */
.sig-bar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  background: var(--psk-brand); color: #fff; padding: 48px 88px 68px;
  display: flex; flex-direction: column; gap: 18px; }
.sig-bar .k { font-family: var(--psk-font-mono); font-size: 16px; letter-spacing: 0.2em; text-transform: uppercase; opacity: 0.9; }
.sig-bar .t { font-family: var(--psk-font-display); font-size: 76px; line-height: 0.92; text-transform: uppercase; }
.sig-bar .b { font-size: 21px; line-height: 1.45; opacity: 0.94; }
