/* --------------------------------------------------------------------------- site.css — minimal one-page portfolio Helvetica-led, subtle colour scheme, generous whitespace. One public page: headline, past-work summary, awards, about, affiliations, request reel. No gate, no media grid, no embeds. Edit the tokens below to re-skin the whole site. --------------------------------------------------------------------------- */ :root { /* palette — intentionally quiet */ --bg: #f7f6f3; --ink: #131310; --ink-soft: #3a3a34; --muted: #74736b; --line: #e2e0d8; --line-strong: #cfcdc3; --accent: #9c5b3b; /* type */ --font: "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif; /* rhythm */ --gutter: clamp(20px, 5vw, 64px); --maxw: 1440px; --measure: 46ch; } *, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--font); font-size: 17px; line-height: 1.55; font-weight: 400; letter-spacing: -0.005em; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } a { color: inherit; text-decoration: none; } ::selection { background: var(--ink); color: var(--bg); } /* --------------------------------------------------------------- typography */ .display { font-size: clamp(2.6rem, 9.2vw, 7.4rem); line-height: 0.94; letter-spacing: -0.045em; font-weight: 700; margin: 0; text-wrap: balance; } .display--tight { font-size: clamp(2.2rem, 7vw, 5rem); } .lede { font-size: clamp(1.05rem, 1.9vw, 1.4rem); line-height: 1.42; letter-spacing: -0.018em; color: var(--ink-soft); max-width: 46ch; margin: 0; } /* The headline is a full sentence, so it is capped below the display default. The vw coefficient is tuned so it holds two lines from ~900px to 1440px: at 7.4vw the middle of that range (1024–1366, i.e. most laptops) collapsed into three lines with a stranded "I connect" on top. */ .hero .display { font-size: clamp(2.3rem, 6.7vw, 6rem); } .hero .lede { max-width: 52ch; font-size: clamp(1rem, 1.5vw, 1.19rem); line-height: 1.5; } .body-copy { max-width: var(--measure); color: var(--ink-soft); margin: 0; } .label { font-size: 0.688rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin: 0; } .mono-meta { font-size: 0.75rem; letter-spacing: 0.02em; color: var(--muted); font-variant-numeric: tabular-nums; } /* ------------------------------------------------------------------ layout */ .shell { min-height: 100vh; display: flex; flex-direction: column; } .wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); } .site-header { padding: clamp(22px, 3.4vw, 40px) 0 clamp(18px, 2.4vw, 28px); } .site-header__inner { display: flex; flex-wrap: wrap; gap: 16px 28px; align-items: baseline; justify-content: space-between; /* no rule under the header — it is just the name and one link */ } .brand { margin: 0; font-size: 0.875rem; font-weight: 700; display: flex; gap: 0.6em; align-items: baseline; } /* The name is the one place the type gets loud: caps, tracked out, bold. The slash and the link stay quiet so the caps read as a choice. */ .brand__name { text-transform: uppercase; letter-spacing: 0.11em; font-weight: 700; } .brand span { color: var(--muted); font-weight: 400; opacity: 0.65; } .brand__link { font-weight: 400; color: var(--muted); border-bottom: 1px solid transparent; padding-bottom: 1px; transition: color 0.18s ease, border-color 0.18s ease; } .brand__link:hover { color: var(--ink); border-bottom-color: var(--ink); } .site-main { flex: 1 0 auto; padding-bottom: 0; } /* -------------------------------------------------------------------- hero */ .hero { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: clamp(32px, 6vw, 88px); align-items: end; padding: clamp(32px, 6vw, 72px) 0 clamp(36px, 5vw, 56px); } .hero__main { display: flex; flex-direction: column; gap: clamp(20px, 3vw, 34px); } .hero__aside { padding-bottom: 6px; } /* ------------------------------------------------- focus / location (rail) */ .focus { margin-bottom: clamp(20px, 3vw, 28px); } /* Accent, so Focus is the first thing the eye lands on in the rail. */ .focus__label { color: var(--accent); margin: 0 0 8px; } .focus__value { margin: 0; font-size: clamp(0.938rem, 1.15vw, 1.06rem); line-height: 1.4; letter-spacing: -0.012em; color: var(--ink); text-wrap: pretty; } /* Location / Also — small caps labels above quiet values, kept distinct. */ .facts { margin: 0; display: flex; flex-direction: column; gap: 14px; } .facts dt { margin: 0 0 3px; } .facts dd { margin: 0; font-size: 0.813rem; line-height: 1.45; color: var(--ink-soft); } /* ------------------------------------------------- past-work summary strip */ /* Flowing inline text: items wrap between their own words, so a long entry like "Paramount, MTV, Nickelodeon, UFC" never strands a short one. */ .summary { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: clamp(16px, 2.2vw, 22px) 0; display: flex; flex-wrap: wrap; gap: 6px 28px; align-items: baseline; } .summary__label { flex: 0 0 auto; min-width: 5.4em; } .summary__text { margin: 0; flex: 1 1 auto; font-size: 0.875rem; line-height: 1.65; letter-spacing: 0.004em; color: var(--ink-soft); text-wrap: pretty; } .summary__sep { color: var(--muted); opacity: 0.65; padding: 0 0.15em; } /* ------------------------------------------------------------------ blocks */ .block { padding: clamp(40px, 6vw, 76px) 0; border-bottom: 1px solid var(--line); } .block--last { border-bottom: 0; padding-bottom: 0; } /* Label column beside a block of content. */ .grid-label { display: grid; grid-template-columns: minmax(0, 0.34fr) minmax(0, 1fr); gap: clamp(16px, 4vw, 56px); align-items: start; } /* ------------------------------------------------------------------ awards */ .awards__lede { margin-bottom: clamp(20px, 3vw, 32px); } .award-groups { display: flex; flex-direction: column; gap: clamp(24px, 3.4vw, 40px); } .award-group__name { margin-bottom: 10px; } .award-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); } .award { display: flex; gap: 4px 24px; align-items: baseline; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid var(--line); } .award__text { color: var(--ink-soft); font-size: 0.875rem; line-height: 1.45; text-wrap: pretty; } /* Year sits right, tabular so the column is even. */ .award__year { flex: 0 0 auto; font-size: 0.75rem; color: var(--muted); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; } /* ------------------------------------------------- variant A: featured + fold */ /* Four awards up front, the full list behind a disclosure. Keeps the page short without deleting anything, and the fold itself signals "there is more". */ .award-list--featured { border-top: 1px solid var(--line-strong); } .award-list--featured .award__text { color: var(--ink); } .awards-more { margin-top: 14px; } .awards-more__summary { list-style: none; cursor: pointer; display: inline-flex; align-items: baseline; gap: 8px; font-size: 0.75rem; letter-spacing: 0.02em; color: var(--muted); border-bottom: 1px solid var(--line-strong); padding-bottom: 2px; transition: color 0.18s ease, border-color 0.18s ease; } .awards-more__summary::-webkit-details-marker { display: none; } .awards-more__summary:hover { color: var(--ink); border-bottom-color: var(--ink); } /* Swap the label on open. */ .awards-more__close { display: none; } .awards-more[open] .awards-more__close { display: inline; } .awards-more[open] .awards-more__open { display: none; } .awards-more[open] .awards-more__summary { margin-bottom: clamp(22px, 3vw, 32px); } .award-groups--nested { padding-top: 2px; } /* --------------------------------------------------- variant B: dense table */ /* Category on the left, its awards stacked beside it — the whole list at roughly half the height, so it all stays above the fold. */ .award-table { display: flex; flex-direction: column; gap: 0; border-top: 1px solid var(--line); } .award-row { display: grid; grid-template-columns: 10.5em minmax(0, 1fr); gap: 8px clamp(16px, 3vw, 40px); align-items: start; padding: clamp(12px, 1.6vw, 16px) 0; border-bottom: 1px solid var(--line); } .award-row__cat { margin: 0; padding-top: 0.15em; } .award-row__items { list-style: none; margin: 0; padding: 0; } .award-row__items .award { padding: 2px 0; border-bottom: 0; } .award-row__items .award + .award { border-top: 1px solid var(--line); padding-top: 6px; margin-top: 6px; } /* ------------------------------------------------------------------ about */ /* The rule is pulled out of the flow into the gutter between the label rail and the copy, so the copy stays on the page's left margin — flush with Awards, Affiliations and the summary strip. -(gap + 34px)/2 centres the mark in that gutter, so it never overhangs the copy at narrow gaps. */ .about-hang { position: relative; } .about-hang .rule--accent { position: absolute; left: calc((clamp(16px, 4vw, 56px) + 34px) / -2); top: 13px; /* optical: sits on the cap height of the first line */ } /* The opening clause, set larger. It carries no terminal punctuation because the sentence continues in the paragraph below it. */ .about__lead { font-size: clamp(1.06rem, 1.5vw, 1.19rem); line-height: 1.5; letter-spacing: -0.018em; color: var(--ink); max-width: 46ch; margin: 0 0 16px; text-wrap: pretty; } .about-hang .body-copy { max-width: 48ch; margin: 0 0 15px; } .about-hang .body-copy:last-child { margin: 0; } /* Narrower measure on the closing credential line: at the body measure it split "Media Studies, / Design and Technology", breaking the degree apart. */ .about__cred { max-width: 44ch; } /* -------------------------------------------------------------- page end */ /* Not a footer. The same short rule that opens the page, so the last line has something to sit against and the page ends deliberately. */ .page-end { padding: clamp(32px, 4.4vw, 44px) 0 clamp(56px, 8vw, 88px); } .affiliations { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; max-width: 62ch; } .affiliations li { font-size: 0.875rem; color: var(--ink-soft); line-height: 1.5; } /* ------------------------------------------------------------- reel */ /* No band. The reel is marked by the same short accent rule that opens the page, so the mark carries the pause instead of a block of colour. The copy stays at body scale: it is a line, not a headline. */ .reel { padding: clamp(28px, 4vw, 40px) 0 0; margin: 0 0 clamp(40px, 6vw, 76px); } .reel .rule--accent { margin-bottom: clamp(18px, 2.6vw, 26px); } .reel__inner { display: flex; flex-wrap: wrap; gap: 14px clamp(24px, 4vw, 56px); align-items: baseline; justify-content: space-between; } .reel__label { flex: 0 0 auto; min-width: 5.4em; margin: 0; } .reel__copy { margin: 0; flex: 1 1 auto; font-size: clamp(1rem, 1.5vw, 1.25rem); line-height: 1.4; letter-spacing: -0.016em; color: var(--ink); text-wrap: pretty; } .reel__link { border-bottom: 1px solid var(--line-strong); padding-bottom: 2px; transition: border-color 0.18s ease, color 0.18s ease; } .reel__link:hover { border-bottom-color: var(--ink); } /* ---------------------------------------------------------------- utilities */ .rule { height: 1px; background: var(--line-strong); border: 0; margin: 0; } .rule--accent { background: var(--accent); width: 34px; height: 2px; } .stack-sm > * + * { margin-top: 12px; } .stack > * + * { margin-top: clamp(20px, 3vw, 32px); } .reveal { animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; } .reveal-2 { animation-delay: 0.08s; } @keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } } :focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; } .skip-link { position: absolute; left: -9999px; } .skip-link:focus { left: var(--gutter); top: 12px; background: var(--ink); color: var(--bg); padding: 8px 12px; z-index: 10; } /* ------------------------------------------------------------- responsive */ @media (max-width: 900px) { .hero, .grid-label { grid-template-columns: minmax(0, 1fr); align-items: start; } .hero { gap: 28px; } .grid-label { gap: 14px; } /* Once the label rail stacks, there is no gutter beside the copy for the rule to hang in. Left absolute, it lands on top of the first line of text. Put it back in the flow, above the quote, where it reads as the same mark that opens the page. */ .about-hang .rule--accent { position: static; margin: 0 0 18px; } } @media (max-width: 520px) { .award { flex-direction: column; gap: 2px; } /* stacked: award text first, year tucked underneath like a datestamp */ .award { gap: 1px; } .award__year { font-size: 0.688rem; } .facts dd, .affiliations li { font-size: 0.813rem; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }