@import "tailwindcss"; /* * Swiss / International Typographic Style. * * Every value below comes from a token in :root. If a component needs a * size, colour, spacing, line-height or tracking value that isn't a token, * the token set is wrong — fix it there, not locally. * * Faces ABC Areal (text), ABC Areal Mono (data). Weights 400 + 500. * Type scale ratio 1.25 from a 17px base: --step--1 … --step-9. * Spacing 4 8 16 24 32 48 64 96 128 (--s-1 … --s-9). * Colour ink on paper, --muted for secondary, cyan for meaning: * --accent for marks (underlines, selection, logo hover), * --accent-text where cyan sets small text (≥ 4.5:1). * Rules 1px; --ink for structure, --rule for separation. * Grid 12 columns (4 below 768px). Meta 1–3, main 4–12, text 4–10. * * Text roles (use these classes; don't restyle ad hoc): * .label sans 500, step--1, ink — names a thing * .meta mono 400, step--1, muted — data: dates, specs, statuses * .note sans 400, step--1, muted — small secondary sentences * .lede sans 400, step-1, muted — a page's one-line introduction */ @font-face { font-family: "ABC Areal"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCAreal-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "ABC Areal"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCAreal-RegularItalic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; } /* Medium covers 500–700 so nothing ever renders a faux or real bold. */ @font-face { font-family: "ABC Areal"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCAreal-Medium.woff2") format("woff2"); font-weight: 500 700; font-style: normal; font-display: swap; } @font-face { font-family: "ABC Areal"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCAreal-MediumItalic.woff2") format("woff2"); font-weight: 500 700; font-style: italic; font-display: swap; } @font-face { font-family: "ABC Areal Mono"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCArealMono-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "ABC Areal Mono"; src: url("https://cdn.anirudh.fi/fonts/areal/ABCArealMono-Medium.woff2") format("woff2"); font-weight: 500 700; font-style: normal; font-display: swap; } @theme { --font-sans: "ABC Areal", ui-sans-serif, system-ui, sans-serif; --font-mono: "ABC Areal Mono", ui-monospace, "SF Mono", monospace; } :root { /* Colour */ --paper: #ffffff; --ink: #0f0f0f; --muted: #5f5f5f; --rule: #d6d6d6; --wash: #f2f2f2; --accent: #509c93; --accent-text: #367169; /* Type scale: ratio 1.25, base 17px. */ --step--1: 0.85rem; --step-0: 1.0625rem; --step-1: 1.328rem; --step-2: 1.66rem; --step-3: 2.075rem; --step-4: 2.594rem; --step-5: 3.242rem; --step-6: 4.053rem; --step-7: 5.066rem; --step-8: 6.333rem; --step-9: 7.916rem; /* Inline elements sized relative to their parent: one step down. */ --step-down: 0.8em; /* Weights */ --regular: 400; --medium: 500; /* Line height: display, heading, body. */ --lh-display: 1; --lh-heading: 1.25; --lh-body: 1.55; /* Tracking tightens as size grows. */ --track-display: -0.04em; --track-title: -0.025em; --track-heading: -0.01em; --track-label: 0.01em; /* Spacing scale; nothing else is used. */ --s-1: 4px; --s-2: 8px; --s-3: 16px; --s-4: 24px; --s-5: 32px; --s-6: 48px; --s-7: 64px; --s-8: 96px; --s-9: 128px; /* Rules */ --hairline: 1px; /* Grid */ --gutter: var(--s-3); --margin: var(--s-4); --measure: 1040px; --ease: 120ms; color-scheme: light dark; } @media (prefers-color-scheme: dark) { :root { --paper: #0f0f0f; --ink: #f2f1ed; --muted: #9d9c97; --rule: #2f2f2d; --wash: #1c1c1b; --accent: #509c93; --accent-text: #509c93; } } @media (min-width: 768px) { :root { --gutter: var(--s-4); --margin: var(--s-6); } } @layer base { html { background: var(--paper); color: var(--ink); font-family: var(--font-sans); font-size: 100%; -webkit-text-size-adjust: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; font-feature-settings: "kern"; } body { font-size: var(--step-0); font-weight: var(--regular); line-height: var(--lh-body); } ::selection { background: color-mix(in srgb, var(--accent) 30%, transparent); color: inherit; } :focus-visible { outline: calc(2 * var(--hairline)) solid var(--accent-text); outline-offset: var(--s-1); } a { color: inherit; text-decoration: underline; text-decoration-thickness: var(--hairline); text-underline-offset: 0.2em; text-decoration-color: var(--accent); transition: color var(--ease), text-decoration-color var(--ease); } a:hover { color: var(--accent-text); text-decoration-color: currentColor; } strong, b, th { font-weight: var(--medium); } img { display: block; max-width: 100%; height: auto; } code, kbd, pre, samp { font-family: var(--font-mono); } } @layer components { /* ---- Text roles -------------------------------------------------- */ .label { font-family: var(--font-sans); font-size: var(--step--1); font-weight: var(--medium); letter-spacing: var(--track-label); color: var(--ink); } .meta { font-family: var(--font-mono); font-size: var(--step--1); font-weight: var(--regular); font-variant-numeric: tabular-nums; color: var(--muted); } .note { font-size: var(--step--1); color: var(--muted); } .lede { font-size: var(--step-1); line-height: var(--lh-heading); color: var(--muted); text-wrap: pretty; } .lede > * + * { margin-top: var(--s-3); } .page-title { font-size: var(--step-4); font-weight: var(--medium); line-height: var(--lh-display); letter-spacing: var(--track-title); text-wrap: balance; } @media (min-width: 1024px) { .page-title { font-size: var(--step-5); } } .draft-flag { font-family: var(--font-mono); font-size: var(--step--1); font-weight: var(--regular); letter-spacing: 0; color: var(--accent-text); vertical-align: middle; } /* ---- Grid -------------------------------------------------------- */ .page { max-width: calc(var(--measure) + 2 * var(--margin)); margin: 0 auto; padding: 0 var(--margin); container-type: inline-size; } .grid-12 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--gutter); } /* Every direct child spans the full width on small screens. */ .grid-12 > * { grid-column: 1 / -1; } @media (min-width: 768px) { .grid-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); } .col-meta { grid-column: 1 / 4; } .col-main, .col-text { grid-column: 4 / -1; } } @media (min-width: 1024px) { /* Running text stops at column 10 to keep a readable measure. */ .col-text { grid-column: 4 / 11; } } /* ---- Header ------------------------------------------------------ */ .site-header { padding: var(--s-5) 0 var(--s-4); align-items: center; row-gap: var(--s-4); border-bottom: var(--hairline) solid var(--ink); } .site-header .logo { display: block; width: var(--s-5); height: var(--s-5); text-decoration: none; } .site-header .logo svg { width: 100%; height: 100%; fill: var(--ink); transition: fill var(--ease); } .site-header .logo:hover svg { fill: var(--accent); } .site-header nav ul { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); list-style: none; margin: 0; padding: 0; } .site-header nav a { font-weight: var(--medium); text-decoration: none; } /* ---- Footer ------------------------------------------------------ */ .site-footer { margin-top: var(--s-9); padding: var(--s-4) 0 var(--s-8); row-gap: var(--s-2); border-top: var(--hairline) solid var(--ink); } .site-footer a { color: var(--ink); } /* ---- Page structure ---------------------------------------------- */ /* * Vertical rhythm: header → page-head (s-8 above, s-7 below) → sections, * each further section s-7 apart → footer s-9 below. */ .page-head { padding: var(--s-8) 0 var(--s-7); row-gap: var(--s-4); } @media (min-width: 768px) { .page-head { align-items: baseline; } } @media (max-width: 767px) { /* On one column the title leads; specs follow. */ .page-head .photo-spec { order: 1; } } .section { row-gap: var(--s-4); } .section + .section { padding-top: var(--s-7); } .section-title { padding-top: var(--s-3); align-self: start; } @media (min-width: 768px) { .section-title { border-top: var(--hairline) solid var(--ink); } } /* Oversized numerals for year groupings — a deliberate break. */ .section-title.numeral { font-size: var(--step-4); line-height: var(--lh-display); letter-spacing: var(--track-title); } .section-foot a { font-weight: var(--medium); text-decoration: none; } /* ---- Home hero: the name, set large, flush left ------------------- */ .hero { padding: var(--s-8) 0 var(--s-7); } .hero > h1 { font-size: var(--step-5); font-weight: var(--medium); line-height: var(--lh-display); letter-spacing: var(--track-display); margin-bottom: var(--s-7); text-wrap: balance; } @media (min-width: 768px) { /* * One line, edge to edge: the name's width is set by the grid, not * the type scale. "Anirudh Oppiliappan" in Areal Medium at this * tracking renders 8.72× its font size wide, so 11.45% of the page * fills it. Re-measure if the name or tracking changes. */ .hero > h1 { font-size: 11.45cqi; white-space: nowrap; } } .hero > p { font-size: var(--step-1); line-height: var(--lh-heading); text-wrap: pretty; } .hero > p + p { margin-top: var(--s-3); } @media (min-width: 768px) { .hero > p { grid-column: 4 / -1; } } @media (min-width: 1024px) { .hero > p { grid-column: 4 / 11; } } /* ---- Entry lists (writing, reading, photos) ---------------------- */ .entries { list-style: none; margin: 0; padding: 0; border-bottom: var(--hairline) solid var(--rule); } .entry { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--s-1); padding: var(--s-3) 0; border-top: var(--hairline) solid var(--rule); } .entry:first-child { border-top-color: var(--ink); } .entry-title { font-weight: var(--medium); text-decoration: none; } .entry-sub { color: var(--muted); } @media (min-width: 768px) { .entries { display: grid; grid-template-columns: subgrid; } .entry { grid-template-columns: subgrid; grid-column: 1 / -1; align-items: baseline; } .entry > .entry-body { grid-column: 1 / 7; } .entry > .entry-aside { grid-column: 7 / -1; text-align: right; } } /* ---- Photos ------------------------------------------------------ */ .photo-grid { columns: 1; column-gap: var(--gutter); } .photo-grid a { display: block; margin-bottom: var(--gutter); break-inside: avoid; } @media (min-width: 768px) { .photo-grid { columns: 2; } } @media (min-width: 1280px) { .photo-grid { columns: 3; } } .photo-spec { display: grid; grid-template-columns: max-content 1fr; gap: var(--s-1) var(--s-3); align-content: start; margin: 0; } .photo-spec dd { margin: 0; } .portrait { width: 50%; margin-bottom: var(--s-5); } @media (min-width: 768px) { .portrait { width: 100%; padding-right: var(--s-4); margin-bottom: 0; } } /* ---- Running text ------------------------------------------------ */ .prose { text-wrap: pretty; } .prose > * + * { margin-top: var(--s-3); } .prose h1, .prose h2 { font-size: var(--step-2); font-weight: var(--medium); line-height: var(--lh-heading); letter-spacing: var(--track-heading); margin-top: var(--s-7); } .prose h3 { font-size: var(--step-1); font-weight: var(--medium); line-height: var(--lh-heading); margin-top: var(--s-6); } .prose h4, .prose h5, .prose h6 { font-size: var(--step-0); font-weight: var(--medium); margin-top: var(--s-5); } .prose h1 + *, .prose h2 + *, .prose h3 + *, .prose h4 + *, .prose h5 + *, .prose h6 + * { margin-top: var(--s-2); } .prose ul, .prose ol { padding-left: var(--s-4); } .prose ul { list-style-type: "–\2002"; } .prose ol { list-style-type: decimal; } .prose li + li, .prose li > ul, .prose li > ol, .prose li > p + p { margin-top: var(--s-2); } .prose li::marker { color: var(--muted); font-variant-numeric: tabular-nums; } .prose blockquote { border-left: var(--hairline) solid var(--ink); padding-left: var(--s-4); } .prose blockquote > * + * { margin-top: var(--s-3); } .prose code { font-size: var(--step-down); background: var(--wash); padding: 0.1em 0.3em; } .prose pre { font-size: var(--step--1); line-height: var(--lh-body); background: var(--wash); padding: var(--s-3) var(--s-4); overflow-x: auto; } .prose pre code { font-size: inherit; background: none; padding: 0; } .prose hr { border: 0; border-top: var(--hairline) solid var(--rule); margin: var(--s-6) 0; } .prose img, .prose figure { margin-top: var(--s-5); margin-bottom: var(--s-5); } .prose img { width: 100%; } .prose figure img { margin: 0; } .prose figcaption { margin-top: var(--s-2); font-size: var(--step--1); color: var(--muted); } .prose table { width: 100%; border-collapse: collapse; font-size: var(--step--1); font-variant-numeric: tabular-nums; } .prose th { text-align: left; border-bottom: var(--hairline) solid var(--ink); } .prose th, .prose td { padding: var(--s-2) var(--s-3) var(--s-2) 0; vertical-align: top; } .prose td { border-bottom: var(--hairline) solid var(--rule); } .prose del { text-decoration: line-through; } /* Footnotes: numbered in the accent colour, set in mono. */ .prose sup { font-size: var(--step-down); line-height: 0; } .prose .footnote-ref a { font-family: var(--font-mono); color: var(--accent-text); text-decoration: none; padding: 0 0.1em; } .prose .footnotes { margin-top: var(--s-7); font-size: var(--step--1); color: var(--muted); } .prose .footnotes hr { border-top-color: var(--ink); margin: 0 0 var(--s-4); } .prose .footnotes li::marker { font-family: var(--font-mono); color: var(--accent-text); } .prose .footnotes li + li { margin-top: var(--s-3); } .prose .footnotes p { display: inline; } .prose .footnote-return { text-decoration: none; color: var(--accent-text); margin-left: var(--s-1); } }