/* public/css/site.css
   The whole look of the site, in one file. The four inks are the spec's tokens,
   verbatim (spec 5.1); every other colour is mixed from them. Red (--c) marks only
   what is live or in the post: the live dot, the postcard stamp and the ரா mark.
   It is never used for reading text. Catamaran is the only type (spec 5.2). */

/* Catamaran, by Pria Ravichandran: SIL Open Font License 1.1 (docs/fonts/Catamaran-OFL.txt).
   Each script's file loads only when a page uses a letter from it. */
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/catamaran-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/catamaran-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/catamaran-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/catamaran-tamil-400-normal.woff2') format('woff2');
  unicode-range: U+0964-0965, U+0B82-0BFA, U+200C-200D, U+20B9, U+25CC;
}
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/catamaran-tamil-600-normal.woff2') format('woff2');
  unicode-range: U+0964-0965, U+0B82-0BFA, U+200C-200D, U+20B9, U+25CC;
}
@font-face {
  font-family: 'Catamaran';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/catamaran-tamil-700-normal.woff2') format('woff2');
  unicode-range: U+0964-0965, U+0B82-0BFA, U+200C-200D, U+20B9, U+25CC;
}

:root {
  --paper: #F7F7F7;
  --ink: #1F1A15;
  --b: #2743B0;
  --c: #B23A2E;
  --buff: #EFE3C8;
  --mute: color-mix(in srgb, var(--ink) 62%, transparent);
  --hair: color-mix(in srgb, var(--ink) 16%, transparent);
  --col: 37rem;
  --gap: 3.2rem;
  --margin: 17rem;
  --sheet: calc(var(--col) + var(--gap) + var(--margin));
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Catamaran', system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  overflow-wrap: break-word;
}
code, pre, kbd, samp { font-family: 'Catamaran', system-ui, sans-serif; }
pre { white-space: pre-wrap; }
input, button, textarea, select { font: inherit; }
img, svg, video { max-width: 100%; height: auto; }
a { color: var(--b); text-underline-offset: 3px; }
p { margin: 0 0 0.6em; }
h1, h2, h3 { line-height: 1.2; }
.label { font-style: italic; font-weight: 400; color: var(--mute); font-size: 0.9em; margin: 0; }

/* The frame. One sheet, centred: on a phone a single column with 18px sides; from
   1100px the letter column, the gap and the margin, with the header across all three,
   so the nav ends at the margin's right edge and the name starts at the column's left
   edge (the alignment rule, spec 5.3). */
.sheet { max-width: var(--sheet); margin: 0 auto; padding: 0 18px; }
.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.4rem 1.2rem;
  padding: 20px 0 28px;
}
.name { font-weight: 700; color: var(--ink); text-decoration: none; }
.mark { color: var(--c); margin-left: 0.35em; }
.site-header nav { display: flex; flex-wrap: wrap; gap: 0.2rem 1.1rem; }
.site-header nav a { font-size: 16px; text-decoration: none; }
.site-header nav a[aria-current="page"] { text-decoration: underline; text-underline-offset: 4px; }
.site-footer {
  border-top: 1px solid var(--hair);
  margin-top: 3rem;
  padding: 1.2rem 0 2.4rem;
  font-size: 15px;
  color: var(--mute);
}
.site-footer p { margin: 0 0 0.3em; }
.site-footer a { margin-right: 1rem; }

@media (min-width: 1100px) {
  .sheet { padding: 0; }
  .site-header { padding: 26px 0 34px; }
}

/* A row: a project's words in the letter column, its one visual in the margin, level
   with the words. On a phone the margin is a narrow strip beside the words; anything
   after the words (the slider) and the aside run the full width below. A project with
   no picture leaves its margin empty, and on a phone its words take the full width. */
.ruled { border-top: 1px solid var(--hair); margin-top: 24px; padding-top: 18px; }
.col { max-width: var(--col); }
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 7rem;
  column-gap: 14px;
  align-items: start;
}
.row > .col { grid-column: 1; }
.row > .margin { grid-column: 2; }
.row > .after, .row > .aside-slot { grid-column: 1 / -1; }
.row:has(> .margin:empty) > .col { grid-column: 1 / -1; }
.project h2 { font-size: 20px; font-weight: 600; line-height: 1.25; margin: 0 0 4px; }
.who { font-size: 15px; color: var(--mute); }
.margin .screen {
  display: block;
  width: 100%;
  max-width: 150px;
  border: 1px solid var(--hair);
  border-radius: 12px;
  box-shadow: 0 3px 10px var(--hair);
}

/* Raja's pen: his own ballpoint, traced to SVG. Each piece is sized by its spot. */
.pen { display: inline-block; width: auto; vertical-align: baseline; }
.pen-hi { height: 2.6rem; }
.pen-signature { height: 2.4rem; }
.pen-lost { width: 100%; max-width: 100%; height: auto; }
.pen-still { height: 2.8rem; }
.pen-aside { width: 100%; max-width: 15rem; height: auto; }
.arrow { margin: 0 0 4px 30px; }
.aside-slot { margin: 12px 0 0; max-width: 15rem; transform: rotate(-3deg); }
/* Undoes the slot's tilt so the link reads straight. */
.aside-reply { display: block; margin-top: 4px; font-size: 15px; transform: rotate(3deg); }

/* Unfinished work: a box drawn on three sides, the fourth only started. */
.open-box { position: relative; border: 1.5px solid var(--ink); border-right: none; padding: 12px 16px; }
.open-box .stub { position: absolute; right: 0; top: 0; height: 36%; border-right: 1.5px solid var(--ink); }

@media (min-width: 1100px) {
  .row { grid-template-columns: var(--col) var(--margin); grid-template-rows: auto 1fr; column-gap: var(--gap); }
  .row > .col, .row > .margin { grid-row: 1; }
  /* The column keeps its measure here, margin or not. */
  .row:has(> .margin:empty) > .col { grid-column: 1; }
  .row > .after { grid-column: 1; grid-row: 2; }
  .row > .aside-slot { grid-column: 2; grid-row: 2; }
  /* The slider follows the words; the screen beside them reaches down past it. */
  .row:has(> .after) > .margin { grid-row: 1 / span 2; }
  /* The aside follows the screen; the words beside them reach down past it. */
  .row:has(> .aside-slot):not(:has(> .after)) > .col { grid-row: 1 / span 2; }
  /* If one project ever has both, the aside waits below the slider rather than overlapping. */
  .row:has(> .after) > .aside-slot { grid-row: 3; }
  .project h2 { font-size: 23px; }
}

/* The letter. The date ends at the margin's right edge, like the nav and the rules. */
.letter .date { text-align: right; font-size: 14px; color: var(--mute); margin: 0 0 0.4rem; }
.hi { margin: 0; }
.letter h1 { font-size: 25px; font-weight: 400; line-height: 1.2; letter-spacing: -0.01em; margin: 4px 0 12px; }
.all-work { margin-top: 18px; }
.latest-writing { margin-top: 18px; }
.latest-writing p { margin: 0 0 0.25em; }
.closing { margin-top: 8px; align-items: center; }
.signature { margin: 22px 0 4px; }

/* The live dot: red, because it is live. It pulses, unless reduced motion is asked for. */
.dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c);
  margin-right: 8px;
  vertical-align: middle;
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c) 45%, transparent); }
  70% { box-shadow: 0 0 0 9px color-mix(in srgb, var(--c) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .dot { animation: none; }
}

/* The small postcard beside the P.S.: a buff Indian postcard, stamped ரா in red. */
.postcard {
  position: relative;
  width: 100%;
  max-width: 150px;
  aspect-ratio: 150 / 96;
  background: var(--buff);
  border: 1px solid var(--hair);
  box-shadow: 0 2px 6px var(--hair);
  transform: rotate(3deg);
}
.postcard-label { position: absolute; left: 8%; top: 8%; font-size: 9px; letter-spacing: 0.12em; color: color-mix(in srgb, var(--ink) 75%, transparent); }
.stamp {
  position: absolute;
  right: 6%;
  top: 8%;
  width: 19%;
  aspect-ratio: 28 / 34;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.4px dashed var(--c);
  color: var(--c);
  font-size: 12px;
}
.postcard .line { position: absolute; left: 8%; right: 30%; border-bottom: 1px solid var(--hair); }
.postcard .line:nth-of-type(3) { top: 42%; }
.postcard .line:nth-of-type(4) { top: 58%; }
.postcard .line:nth-of-type(5) { top: 74%; }

@media (min-width: 1100px) {
  .pen-hi { height: 3.4rem; }
  .letter h1 { font-size: 33px; }
}

/* The commute slider: a quiet blue panel; the numbers stay in ink. */
.try {
  background: color-mix(in srgb, var(--b) 6%, transparent);
  border-radius: 8px;
  padding: 10px 14px;
  margin-top: 8px;
  max-width: 30rem;
}
.try p { margin: 0; }
.try input[type="range"] { display: block; width: 100%; margin-top: 6px; accent-color: var(--b); }
.try .method { margin-top: 8px; font-size: 14px; color: var(--mute); }

/* Page headings, on every page but the letter. */
main > h1, .page-head h1 { font-size: 28px; font-weight: 600; margin: 0 0 8px; }
.question { font-size: 19px; margin: 0 0 4px; }
@media (min-width: 1100px) {
  main > h1, .page-head h1 { font-size: 34px; }
}

/* A project's own page: the row again, with the visual larger. On a phone the visual
   comes first, above the words; from 1100px it fills the margin. */
.feature { grid-template-columns: minmax(0, 1fr); row-gap: 16px; }
.feature > .margin { grid-column: 1; grid-row: 1; }
.feature > .col { grid-column: 1; grid-row: 2; }
.feature .margin .screen { max-width: 280px; }
.story { margin-top: 18px; }
.project-page details { margin-top: 18px; }
.project-page .proof { margin-top: 18px; }
.project-page summary { cursor: pointer; color: var(--b); }
.project-page details[open] summary { margin-bottom: 8px; }
.source { font-size: 15px; color: var(--mute); }
@media (min-width: 1100px) {
  .feature { grid-template-columns: var(--col) var(--margin); grid-template-rows: auto; }
  .feature > .col, .feature > .margin { grid-row: 1; }
  .feature > .margin { grid-column: 2; }
  .feature .margin .screen { max-width: 100%; }
}

/* The writing list: one ruled item per essay, the date first, as a label. */
.essay-item h2 { font-size: 20px; font-weight: 600; margin: 2px 0 4px; }
.essay-item h2 a { text-decoration: none; }
.essay-item h2 a:hover { text-decoration: underline; }
@media (min-width: 1100px) { .essay-item h2 { font-size: 23px; } }

/* An essay: a plain reading page, 18px, in the letter column. */
.essay > h1 { font-size: 28px; font-weight: 600; margin: 2px 0 20px; }
.essay-body { font-size: 18px; line-height: 1.65; }
.essay-body p { margin: 0 0 1em; }
.essay-body img { display: block; margin: 1.2em auto; border-radius: 6px; }
.essay-body blockquote { margin: 1.4em 0; padding-left: 1em; border-left: 3px solid var(--hair); font-size: 1.1em; }
.essay-body hr { border: none; border-top: 1px solid var(--hair); margin: 2em 0; }
.essay-body ul, .essay-body ol { padding-left: 1.3em; margin: 0 0 1em; }
.essay-body li { margin-bottom: 0.4em; }
.essay-close { margin-top: 2em; }
.also { font-size: 15px; }
/* A deck: its slides in one row, each snapping into place, the next one peeking in. */
.deck { overflow-x: auto; scroll-snap-type: x mandatory; margin: 0 0 12px; }
.deck ol { display: flex; gap: 12px; list-style: none; margin: 0; padding: 0 0 10px; }
.deck li { flex: 0 0 85%; margin: 0; scroll-snap-align: start; }
.deck img { display: block; width: 100%; height: auto; margin: 0; }
.deck-text { margin-top: 18px; }
.deck-text summary { cursor: pointer; color: var(--b); }
.deck-text[open] summary { margin-bottom: 1em; }
.deck-text h3 { margin: 1.6em 0 0.4em; }
.deck-text table { border-collapse: collapse; margin: 0 0 1em; font-size: 16px; }
.deck-text th, .deck-text td { padding: 4px 14px 4px 0; border-bottom: 1px solid var(--hair); }
/* Substack's subscribe box: as wide as the column allows, up to Substack's 480px. The
   box arrives when a reader nears it (public/js/subscribe.js); its room is kept. */
.subscribe { margin: 2em 0; min-height: 322px; }
.subscribe iframe { display: block; width: 100%; max-width: 480px; height: 320px; border: 1px solid var(--hair); }
@media (min-width: 1100px) { .essay > h1 { font-size: 34px; } }

/* Now: this month large, earlier months smaller below. */
.now-latest { font-size: 19px; }
.now-latest .label { font-size: 15px; margin-bottom: 6px; }
.now-log { margin-top: 2.4rem; }
.now-log .label { font-size: 15px; }

/* The CV: plain, in the letter column. */
.cv .lede { font-size: 19px; }
.cv h2.label { font-size: 15px; margin: 0 0 10px; }
.cv-item { margin-bottom: 18px; }
.cv-item h3 { font-size: 18px; font-weight: 600; margin: 0; }
.cv-item .who { margin-bottom: 4px; }
.skill { font-style: italic; margin-right: 0.4em; }

/* The 404 page: a note in Raja's hand, the cat and a way home. */
.not-found { padding: 2rem 0 3rem; }
.not-found h1 { font-weight: 400; margin: 0 0 1rem; }
.not-found .cat { display: block; width: 100%; max-width: 420px; height: auto; margin: 8px 0 18px; }

/* Write to me: the large postcard form. The same buff card as the small postcard, but
   upright (a tilted form is hard to type in) and the width of the letter column. "POST
   CARD" sits top left and the ரா stamp top right; the name field beside the stamp keeps
   clear of it. The fields are written in ink on the card, the message on ruled lines.
   The button is blue, like every link; red stays on the stamp. On buff, muted text and
   a hairline are too faint to read, so the labels are in ink and each field's edge is
   --line, a darker mix of ink (3 to 1 or more against the card). */
.postcard-form {
  --line: color-mix(in srgb, var(--ink) 45%, transparent);
  position: relative;
  max-width: var(--col);
  margin-top: 20px;
  padding: 2.4rem 16px 20px;
  background: var(--buff);
  border: 1px solid var(--hair);
  box-shadow: 0 3px 10px var(--hair);
}
.postcard-form .postcard-label { left: 16px; top: 14px; font-size: 12px; }
.postcard-form .stamp { right: 16px; top: 16px; width: 3.4rem; font-size: 24px; border-width: 1.5px; }
.postcard-form > label:first-of-type { margin-right: 4.4rem; }
.postcard-form label {
  display: block;
  margin-top: 12px;
  font-size: 15px;
  font-style: italic;
  color: var(--ink);
}
.postcard-form input, .postcard-form textarea {
  display: block;
  width: 100%;
  margin-top: 2px;
  padding: 4px 2px;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-size: 17px;
  font-style: normal;
}
/* The message: each line of text sits on a faint ruled line, 32px apart, scrolling
   with it, inside a box drawn in --line so the field's edge is easy to see. */
.postcard-form textarea {
  padding: 0 4px;
  border: 1px solid var(--line);
  line-height: 32px;
  background-image: repeating-linear-gradient(to bottom, transparent 0, transparent 31px, var(--hair) 31px, var(--hair) 32px);
  background-attachment: local;
  resize: vertical;
}
.postcard-form input:focus-visible, .postcard-form textarea:focus-visible, .postcard-form button:focus-visible {
  outline: 2px solid var(--b);
  outline-offset: 2px;
}
.postcard-form button {
  margin-top: 18px;
  padding: 6px 22px;
  border: 1.5px solid var(--b);
  border-radius: 4px;
  background: transparent;
  color: var(--b);
  font-weight: 600;
  cursor: pointer;
}
.postcard-form button:hover { background: color-mix(in srgb, var(--b) 8%, transparent); }
/* The trap: moved off screen, never display: none, so a bot still finds it. */
.trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
/* An error the Worker sent back: hidden until the address names it (#error-email).
   !important because the hidden attribute's rule above is !important too. In ink,
   with a blue rule on the left; red is never reading text. */
.form-error {
  max-width: var(--col);
  margin: 16px 0 0;
  padding: 8px 14px;
  border-left: 3px solid var(--b);
  background: color-mix(in srgb, var(--b) 6%, transparent);
  scroll-margin-top: 16px;
}
.form-error:target { display: block !important; }
@media (min-width: 1100px) {
  .postcard-form { padding: 2.8rem 28px 26px; }
  .postcard-form .postcard-label { left: 28px; top: 18px; }
  .postcard-form .stamp { right: 28px; top: 20px; width: 3.8rem; font-size: 27px; }
  .postcard-form > label:first-of-type { margin-right: 5.2rem; }
}
