/* Site stylesheet (ADR 0003): a comparison listing on the Hintapiste design system (DU-116 production tokens).
   Projects are offers on shared spec rows (filter, sort, compare), the career is a timeline, the search growth is
   one line chart. Consumes custom properties from tokens.css only: no raw colours here. Mobile first; wide layouts
   from 640px and 1024px. Light only: a white canvas, a Midnight Ink header, bordered white surfaces, Lato for text
   and Barlow Black for the page title, Lingonberry links and focus, and the filled action on one button per page. */

/* ---------- 1. Fonts ---------- */
/* Lato 400 and 700 (Lato has no 600, so semibold renders bold) and Barlow 900 for the page title, Latin and
   Latin Extended, from fontsource 5.3.0 (OFL). Static fonts, so the CV PDF embeds CID fonts, not Type 3. */
@font-face { font-family: "Lato"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/Lato-Regular-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/Lato-Regular-latin.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: "Lato"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/Lato-Bold-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/Lato-Bold-latin.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: "Barlow"; font-style: normal; font-weight: 900; font-display: swap; src: url("../fonts/Barlow-Black-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Barlow"; font-style: normal; font-weight: 900; font-display: swap; src: url("../fonts/Barlow-Black-latin.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; }

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { color-scheme: light; font-size: 100%; -webkit-text-size-adjust: 100%; scroll-padding-top: 80px; }
body {
  margin: 0; background: var(--c-bg); color: var(--c-fg);
  font-family: var(--f-sans); font-size: var(--t-body); line-height: var(--lh-body);
  font-feature-settings: "kern";
}
h1, h2, h3 { margin: 0; font-weight: var(--fw-bold); color: var(--c-fg); text-wrap: balance; }
h1 { font-family: var(--f-display); font-weight: var(--fw-black); font-size: var(--t-h1); line-height: var(--lh-h1); letter-spacing: var(--tr-display); }
h2 { font-size: var(--t-xl); line-height: var(--lh-xl); letter-spacing: var(--tr-display); }
h3 { font-size: var(--t-lg); line-height: var(--lh-lg); font-weight: var(--fw-semibold); }
p, ul, ol, dl, dd { margin: 0; }
a { color: var(--c-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: var(--focus-width) solid var(--c-focus); outline-offset: var(--focus-offset); border-radius: var(--r-control); }
main:focus { outline: none; }
button { font: inherit; }
@media (max-width: 639.98px) { [lang="fi"] main p:not(.lede), [lang="fi"] main dd { hyphens: auto; } }
time, .rrow__date, .offer__specs, .facet__n, .trend, .tl, .facts, .cv-role__dates, .period__range { font-variant-numeric: tabular-nums; }
.nohyph { hyphens: manual; }
.meta { color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.muted { color: var(--c-muted); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.lede { max-width: 65ch; font-size: var(--t-lead); line-height: var(--lh-lead); color: var(--c-fg-2); }
.bullets { padding-left: 1.2em; max-width: var(--w-prose); color: var(--c-fg-2); }
.bullets li + li { margin-top: var(--s-2); }
/* Reading text is 16px/1.5 (the one documented override in design/vendor/hintapiste/SOURCE.json): all of main on
   the reading pages, and the home page's prose (second intro paragraph, project and result descriptions). Tables,
   meta and tags keep their token sizes. */
[data-page="project"] main, [data-page="cv"] main, [data-page="experience"] main,
[data-page="home"] .lead .lede + .lede, [data-page="home"] .offer__what, [data-page="home"] .rrow__out { font-size: var(--t-prose); line-height: var(--lh-prose); }
.links { list-style: none; padding: 0; display: grid; gap: var(--s-2); }

.wrap { width: 100%; max-width: var(--w-max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.section { padding-top: var(--s-12); }
.section--last { padding-bottom: var(--section-y); }
.section--tight { padding-top: var(--s-10); padding-bottom: var(--s-10); }
.page { padding-top: var(--s-4); padding-bottom: var(--section-y); }
.section__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s-2) var(--s-6); margin-bottom: var(--s-4); }
.page__title { margin-bottom: var(--s-6); font-size: var(--t-h1); line-height: var(--lh-h1); }
.block { margin-top: var(--s-12); }
.block > h2, section > h2 { margin-bottom: var(--s-4); }
.section__head > h2 { margin-bottom: 0; }

.skip { position: absolute; left: var(--s-4); top: -100px; padding: var(--s-3) var(--s-4); background: var(--c-surface); color: var(--c-link); box-shadow: var(--sh-floating); border-radius: var(--r-control); z-index: 100; text-decoration: none; }
.skip:focus { top: var(--s-4); }


/* Breadcrumbs: a drawn chevron between steps, the current page as plain text. */
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; list-style: none; margin: 0 0 var(--s-2); padding: 0; font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-muted); }
.crumbs li { display: inline-flex; align-items: center; }
.crumbs li + li::before { content: ""; width: 6px; height: 6px; margin: 0 var(--s-3) 0 var(--s-2); border-right: 1.5px solid var(--c-muted); border-top: 1.5px solid var(--c-muted); transform: rotate(45deg); }
.crumbs a { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); color: var(--c-fg-2); text-decoration: none; }
.crumbs a:hover { color: var(--c-fg); text-decoration: underline; }
.crumbs [aria-current] { color: var(--c-fg-2); }

/* Panels: the ordinary surface (white, 1px perimeter ring, 8px radius) of the offer box, spec sheet and chart. */
.panel { background: var(--c-surface); border: 1px solid var(--c-border); box-shadow: var(--sh-surface); border-radius: var(--r-surface); padding: var(--s-5); }
.panel__title { font-size: var(--t-lg); line-height: var(--lh-lg); margin-bottom: var(--s-4); }
.panel__more { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); margin-top: var(--s-2); }
@media (min-width: 640px) { .panel { padding: var(--s-6); } }

/* Spec sheet: label and value on one hairline row. */
.spec > div { display: grid; gap: var(--s-1); padding: var(--s-3) 0; border-top: 1px solid var(--c-border); }
.spec > div:last-child { border-bottom: 1px solid var(--c-border); }
.spec dt { font-weight: var(--fw-semibold); color: var(--c-fg); }
.spec dt a { color: var(--c-fg); text-decoration-color: var(--c-control); }
.spec dt a:hover { text-decoration-color: var(--c-fg); }
.spec dd { color: var(--c-fg-2); }
@media (min-width: 640px) { .spec > div { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); column-gap: var(--s-6); } }
.spec--compact > div, .spec--compact > div:last-child { grid-template-columns: 7.5rem minmax(0, 1fr); column-gap: var(--s-4); padding: var(--s-2) 0; border-bottom: 0; font-size: var(--t-sm); line-height: var(--lh-sm); }
.spec--compact > div:first-child { border-top: 0; }
.spec--compact dt { font-weight: var(--fw-regular); color: var(--c-muted); }
.spec--compact dd { color: var(--c-fg); overflow-wrap: anywhere; }
.spec--compact > .spec__wide { grid-template-columns: minmax(0, 1fr); }
.tags { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-2); list-style: none; margin: 0; padding: 0; }
.tags li { padding: 1px var(--s-2); border: 1px solid var(--c-border); border-radius: var(--r-control); color: var(--c-fg-2); font-size: var(--t-xs); line-height: var(--lh-xs); }

/* ---------- 3. Header ---------- */
.nav { position: sticky; top: 0; z-index: 50; background: var(--c-header); color: var(--c-on-header); }
.nav :focus-visible { outline-color: var(--c-focus-contrast); }
.nav__row { display: flex; align-items: center; justify-content: space-between; min-height: 64px; gap: var(--s-3); }
.brand { display: flex; flex-direction: column; text-decoration: none; color: var(--c-on-header); line-height: var(--lh-sm); }
.brand__name { font-weight: var(--fw-semibold); font-size: var(--t-md); white-space: nowrap; }
.brand__role { display: none; color: var(--c-on-header-2); font-size: var(--t-sm); }
.nav__links { display: none; list-style: none; margin: 0; padding: 0; gap: var(--s-1); align-items: center; }
.nav__links a { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); padding: 0 var(--s-3); color: var(--c-on-header-2); text-decoration: none; border-bottom: 2px solid transparent; }
.nav__links a:hover { color: var(--c-on-header); }
.nav__links a[aria-current="page"] { color: var(--c-on-header); font-weight: var(--fw-semibold); border-bottom-color: var(--c-on-header); }
.nav__util { display: none; }
.nav__util a { color: var(--c-on-header-2); font-size: var(--t-sm); text-decoration: none; white-space: nowrap; min-height: var(--ctl-h-touch); display: inline-flex; align-items: center; }
.nav__util a:hover { color: var(--c-on-header); text-decoration: underline; }
.nav__actions { display: flex; align-items: center; gap: var(--s-2); }
.menu-btn { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--ctl-h-touch); padding: 0 var(--s-3); background: transparent; border: 1px solid var(--c-on-header-2); border-radius: var(--r-control); color: var(--c-on-header); cursor: pointer; }
.menu-btn svg { width: 18px; height: 18px; }
.sheet { display: none; background: var(--c-surface); border-bottom: 1px solid var(--c-border); box-shadow: var(--sh-floating); }
.sheet[data-open="true"] { display: block; }
.sheet ul { list-style: none; margin: 0; padding: var(--s-2) 0; }
.sheet li a { display: flex; align-items: center; min-height: var(--ctl-h-action); padding: 0 var(--gutter); color: var(--c-fg-2); text-decoration: none; font-size: var(--t-lg); }
.sheet li a[aria-current="page"] { color: var(--c-fg); font-weight: var(--fw-semibold); background: var(--c-selected); }
.sheet__util { display: flex; flex-wrap: wrap; gap: 0 var(--s-6); padding: var(--s-2) var(--gutter) var(--s-4); border-top: 1px solid var(--c-border); }
.sheet__util a { font-size: var(--t-sm); color: var(--c-fg-2); min-height: var(--ctl-h-touch); display: inline-flex; align-items: center; }
@media (min-width: 640px) { .brand__role { display: block; } }
@media (min-width: 1024px) {
  .nav__row { min-height: 72px; }
  .nav__links, .nav__util { display: flex; }
  .menu-btn, .sheet { display: none !important; }
}

/* ---------- 4. Buttons ---------- */
/* Hintapiste button primitive: 8px radius, semibold label, no pills. Only the one dominant action per screen
   (the in-content contact button) is filled in the warm action colour; the rest are neutral. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: var(--ctl-h-action); padding: 0 var(--ctl-px-action); border-radius: var(--r-control); font-weight: var(--fw-semibold); font-size: var(--t-md); line-height: var(--lh-md); text-decoration: none; border: 1px solid transparent; cursor: pointer; transition: background-color var(--d-fast) var(--d-ease), border-color var(--d-fast) var(--d-ease); }
.btn--primary { background: var(--c-action); color: var(--c-on-action); }
.btn--primary:hover { background: var(--c-action-hover); }
.btn--primary:active { background: var(--c-action-active); }
.btn--secondary { background: var(--c-surface); color: var(--c-fg); border-color: var(--c-control); }
.btn--secondary:hover { background: var(--c-selected); }
/* The header button is outlined so each screen has at most one filled button. */
.btn--outline { background: var(--c-surface); color: var(--c-link); border-color: var(--c-control); }
.btn--outline:hover, .btn--outline[aria-current="page"] { background: var(--c-selected); }
/* On the Midnight Ink header the outline button reads light-on-dark, as in the Hintapiste shell. */
.nav .btn--outline { background: transparent; color: var(--c-on-header); border-color: var(--c-on-header-2); }
.nav .btn--outline:hover, .nav .btn--outline[aria-current="page"] { background: transparent; border-color: var(--c-on-header); box-shadow: inset 0 0 0 1px var(--c-on-header); }
.btn--sm { min-height: var(--ctl-h-touch); padding: 0 var(--ctl-px-md); font-size: var(--t-button); line-height: var(--lh-button); white-space: nowrap; }
.actions { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }

/* ---------- 5. Home: lead with spec sheet, offer panel and trend ---------- */
.lead { display: grid; grid-template-areas: "intro" "side" "glance"; gap: var(--s-8); padding-top: var(--s-8); }
.lead__hook { font-size: var(--t-h1); line-height: var(--lh-h1); max-width: 22ch; overflow-wrap: break-word; }
.lead .lede { margin-top: var(--s-4); }
.lead .lede + .lede { margin-top: var(--s-3); font-size: var(--t-body); line-height: var(--lh-body); }
.lead__intro { grid-area: intro; }
.lead__side { grid-area: side; }
.glance { grid-area: glance; }
.glance h2 { font-size: var(--t-lg); line-height: var(--lh-lg); margin-bottom: var(--s-2); }
.lead__side { display: grid; gap: var(--s-6); align-content: start; }
.card h2 { font-size: var(--t-xl); line-height: var(--lh-xl); margin-bottom: var(--s-3); }
.card__actions { display: grid; gap: var(--s-3); margin-top: var(--s-5); }
.card__links { display: flex; flex-wrap: wrap; gap: 0 var(--s-6); margin-top: var(--s-3); font-size: var(--t-sm); }
.card__links a { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); }
@media (min-width: 1024px) {
  .lead { grid-template-areas: "intro side" "glance side"; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); grid-template-rows: auto 1fr; column-gap: var(--s-12); row-gap: var(--s-16); padding-top: var(--s-8); }
  /* Side by side, the two offer buttons leave room for the chart on the first screen. */
  .lead .card__actions { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .lead__side { gap: var(--s-4); }
}
/* Home rhythm: sections stand apart; each heading sits close to its own list. */
.lead ~ .section { padding-top: var(--s-16); }
.lead ~ .section .section__head { margin-bottom: var(--s-2); }
@media (min-width: 1024px) { .lead ~ .section { padding-top: var(--s-16); } }

/* Trend chart: one line on dashed gridlines; labels are HTML so they never scale with the plot. */
.trend { margin: 0; }
.trend__plot { position: relative; height: 168px; margin-left: 2.25rem; }
.trend__plot svg { display: block; width: 100%; height: 100%; overflow: visible; }
.trend__grid { stroke: var(--c-border); stroke-width: 1; stroke-dasharray: 2 4; }
.trend__area { fill: var(--c-selected); }
.trend__line { fill: none; stroke: var(--c-chart); stroke-width: 2; stroke-linejoin: round; }
/* The one authored motion: the series draws in from the left. */
.trend__plot svg { animation: reveal 1.2s var(--d-ease) both; }
@keyframes reveal { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.trend__y { position: absolute; left: -2.25rem; width: 1.75rem; transform: translateY(-50%); text-align: right; font-size: var(--t-xs); line-height: var(--lh-xs); color: var(--c-muted); }
.trend__dot { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: var(--c-chart); box-shadow: 0 0 0 3px var(--c-surface); transform: translate(-50%, -50%); }
.trend__val { position: absolute; transform: translate(calc(-100% - 12px), -50%); padding: 0 var(--s-1); background: var(--c-surface); color: var(--c-fg); font-weight: var(--fw-semibold); font-size: var(--t-sm); line-height: var(--lh-sm); }
.trend__x { display: flex; justify-content: space-between; gap: var(--s-4); margin: var(--s-2) 0 0 2.25rem; font-size: var(--t-xs); line-height: var(--lh-xs); }
.trend__cap { display: grid; gap: var(--s-3); margin-top: var(--s-4); }
.trend__title { font-weight: var(--fw-semibold); }
.trend__stats { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-8); }
.trend__stats dt { color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.trend__stats dd { color: var(--c-fg); font-weight: var(--fw-semibold); font-size: var(--t-lg); line-height: var(--lh-lg); }

/* ---------- 6. Rows: results and project offers ---------- */
.rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--c-border); }
.rows > li { border-bottom: 1px solid var(--c-border); padding: var(--s-4) 0; }
.rowhead { display: none; }

/* Result row: date · what · result */
.rrow { display: grid; gap: var(--s-1); scroll-margin-top: 88px; }
.rrow__date { color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.rrow__date:empty { display: none; }
.rrow__title { font-weight: var(--fw-semibold); color: var(--c-fg); }
.rrow__title a { color: inherit; text-decoration-color: var(--c-control); }
.rrow__title a:hover { text-decoration-color: var(--c-fg); }
.rrow__out { color: var(--c-fg-2); max-width: var(--w-prose); }
.rrow:target { background: var(--c-selected); box-shadow: -8px 0 0 var(--c-selected), 8px 0 0 var(--c-selected); }

/* Offer row: name, what it is and technologies · type · status · updated (· compare) */
.offers, .rowhead { --cols: minmax(0, 1fr) 9rem 8.5rem 8.5rem; }
.offers { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--c-border); }
.offer { display: grid; gap: var(--s-3); padding: var(--s-5) 0; border-bottom: 1px solid var(--c-border); }
.offer__fig { margin-top: var(--s-2); color: var(--c-fg-2); font-size: var(--t-sm); line-height: var(--lh-sm); }
.offer__fig strong { margin-right: var(--s-1); color: var(--c-fg); font-size: var(--t-lg); line-height: var(--lh-lg); font-variant-numeric: tabular-nums; }
.offer__name { font-size: var(--t-lg); line-height: var(--lh-lg); }
.offer__name a { color: var(--c-fg); text-decoration-color: var(--c-control); }
.offer__name a:hover { text-decoration-color: var(--c-fg); }
.offer__what { margin-top: var(--s-1); color: var(--c-fg-2); max-width: var(--w-prose); }
.offer .tags { margin-top: var(--s-3); }
.offer__specs { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-5); font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-fg-2); }
.offer__specs div { display: flex; gap: var(--s-2); }
.offer__specs dt { color: var(--c-muted); }
.offer__specs dt::after { content: ":"; }
.cmp { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--ctl-h-touch); font-size: var(--t-sm); color: var(--c-fg-2); cursor: pointer; justify-self: start; }
.cmp input { width: 18px; height: 18px; margin: 0; accent-color: var(--c-fg); }
.cmp:has(input:disabled) { color: var(--c-muted); cursor: not-allowed; }
@media (min-width: 640px) {
  .rrow { grid-template-columns: 9rem minmax(0, 1fr); column-gap: var(--s-6); }
  .rrow__date { padding-top: 2px; }
  .rrow__date:empty { display: block; }
  /* A row without a date column (the home journey, the demo's products) spans the whole width. */
  .rrow > .rrow__body:only-child { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .rowhead { display: grid; grid-template-columns: var(--cols); column-gap: var(--s-6); padding-bottom: var(--s-2); color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
  .rowhead + .rows, .rowhead + .offers, .rowhead + .matrix { border-top-color: var(--c-control); }
  .offer { grid-template-columns: var(--cols); column-gap: var(--s-6); align-items: baseline; }
  .offer__specs { display: contents; }
  .offer__specs div { display: block; }
  .offer__specs dt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .rrow__body { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); column-gap: var(--s-6); }
  .rrow__out { font-size: var(--t-md); line-height: var(--lh-md); }
}

/* Status: an icon plus text, never colour alone */
.status { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--c-fg-2); }
.status svg { flex: none; width: 16px; height: 16px; color: var(--c-fg-2); }
.status--shipped svg { color: var(--c-positive); }
.status--paused svg { color: var(--c-warning); }
.status--archived svg, .status--abandoned svg { color: var(--c-missing); }

/* ---------- 7. Projects listing: facets, search, sort, compare ---------- */
.listing { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
.listing .offers, .listing .rowhead { --cols: minmax(0, 1fr) 7.5rem 7.5rem 6.5rem 5.5rem; }
.facets__title { font-size: var(--t-lg); line-height: var(--lh-lg); }
.facets__tools { display: grid; gap: var(--s-3); margin-top: var(--s-3); }
.field { display: grid; gap: var(--s-1); font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-fg-2); }
.field input, .field select { min-height: var(--ctl-h-touch); width: 100%; padding: 0 var(--ctl-px-sm); background: var(--c-surface); color: var(--c-fg); border: 1px solid var(--c-control); border-radius: var(--r-control); font: inherit; font-size: var(--t-md); }
.field input::placeholder { color: var(--c-muted); }
.facet__title { margin: var(--s-5) 0 var(--s-2); font-family: var(--f-sans); font-size: var(--t-sm); line-height: var(--lh-sm); font-weight: var(--fw-semibold); color: var(--c-fg-2); }
.facet { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; margin: 0; padding: 0; }
.facet__opt { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--ctl-h-touch); padding: 0 var(--s-3); border: 1px solid var(--c-control); border-radius: var(--r-control); color: var(--c-fg-2); text-decoration: none; font-size: var(--t-sm); }
.facet__opt:hover { background: var(--c-surface); color: var(--c-fg); }
.facet__opt[aria-current="true"] { background: var(--c-selected); border-color: var(--c-selected-border); color: var(--c-fg); font-weight: var(--fw-semibold); }
.facet__opt[aria-current="true"]::before { content: ""; flex: none; width: 5px; height: 9px; margin: -3px 2px 0 0; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); }
.facet__n { color: var(--c-muted); font-size: var(--t-xs); }
.facet__opt[aria-current="true"] .facet__n { color: var(--c-fg-2); }
.facets__reset { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); margin-top: var(--s-3); font-size: var(--t-sm); }
.count { color: var(--c-fg-2); font-size: var(--t-sm); margin-bottom: var(--s-3); }
.notice { margin-top: var(--s-4); padding: var(--s-4) var(--s-5); background: var(--c-subtle); border: 1px solid var(--c-border); border-radius: var(--r-surface); color: var(--c-fg-2); max-width: var(--w-prose); }
/* On phones each facet group is one scrolling row, so the offers start within the first screen. */
@media (max-width: 1023.98px) {
  .facets__tools { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; }
  .facet { flex-wrap: nowrap; overflow-x: auto; margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scrollbar-width: none; }
  .facet__opt { white-space: nowrap; }
  .facet__title { margin-top: var(--s-4); }
}
@media (min-width: 1024px) {
  .listing { grid-template-columns: 13rem minmax(0, 1fr); column-gap: var(--s-8); align-items: start; }
  .listing .offer, .listing .rowhead { column-gap: var(--s-4); }
  .facets { position: sticky; top: 96px; }
  .facet { flex-direction: column; gap: var(--s-1); }
  .facet__opt { display: flex; justify-content: space-between; border-color: transparent; }
  .facet__opt[aria-current="true"]::before { order: 2; margin-left: auto; }
  .facet__opt[aria-current="true"] .facet__n { order: 3; }
}

/* Comparison tray and table */
.tray { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; background: var(--c-surface); border-top: 1px solid var(--c-control); box-shadow: var(--sh-floating); padding: var(--s-3) 0 calc(var(--s-3) + env(safe-area-inset-bottom, 0px)); }
.tray__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-4); }
.tray__count { font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-fg); }
.tray__actions { display: flex; gap: var(--s-2); }
/* Disabled stays legible and is not shown by opacity alone (Hintapiste state.disabled). */
.btn:disabled, .btn:disabled:hover { background: var(--c-disabled); color: var(--c-muted); border-color: var(--c-border); cursor: not-allowed; }
.has-tray { padding-bottom: 96px; }
.cmpview { margin-top: var(--s-10); scroll-margin-top: 88px; }
.cmpview:focus { outline: none; }
.cmpview h2 { margin-bottom: var(--s-4); }
.cmpview__scroll { overflow-x: auto; border: 1px solid var(--c-border); border-radius: var(--r-surface); background: var(--c-surface); }
.cmptable { width: 100%; border-collapse: collapse; font-size: var(--t-sm); line-height: var(--lh-sm); }
.cmptable th, .cmptable td { padding: var(--s-3) var(--s-4); text-align: left; vertical-align: top; border-bottom: 1px solid var(--c-border); }
.cmptable tbody tr:last-child > * { border-bottom: 0; }
.cmptable td { min-width: 13rem; color: var(--c-fg-2); }
.cmptable thead th { font-size: var(--t-md); line-height: var(--lh-md); }
.cmptable tbody th { width: 8rem; color: var(--c-muted); font-weight: var(--fw-regular); white-space: nowrap; }

/* ---------- 8. Experience: career timeline and periods ---------- */
.history { margin-bottom: var(--s-10); }
.tl { --label: 0px; }
.tl__years { position: relative; height: calc(var(--t-xs) * var(--lh-xs)); margin: 0 0 var(--s-2) var(--label); font-size: var(--t-xs); line-height: var(--lh-xs); color: var(--c-muted); }
.tl__years span { position: absolute; top: 0; }
.tl__years span:nth-child(even) { display: none; }
.tl__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.tl__row { display: grid; gap: var(--s-2); }
.tl__label { font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-fg-2); }
.tl__label strong { color: var(--c-fg); font-weight: var(--fw-semibold); }
.tl__label .meta { white-space: nowrap; }
.tl__track { position: relative; height: 12px; border-radius: var(--r-control); background-color: var(--c-subtle); background-image: linear-gradient(to right, var(--c-border) 1px, transparent 1px); background-size: 11.111% 100%; }
.tl__bar { position: absolute; top: 0; bottom: 0; min-width: 6px; border-radius: var(--r-control); background: var(--c-control); }
.tl__bar--now { background: var(--c-chart); }
@media (min-width: 640px) { .tl__years span:nth-child(even) { display: block; } }
@media (min-width: 1024px) {
  .tl { --label: 24rem; }
  .tl__years { margin-left: calc(var(--label) + var(--s-6)); }
  .tl__row { grid-template-columns: var(--label) minmax(0, 1fr); column-gap: var(--s-6); align-items: center; }
}

.jump { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-bottom: var(--s-6); }
.jump a { display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); padding: 0 var(--s-3); border-radius: var(--r-control); color: var(--c-fg-2); text-decoration: none; font-size: var(--t-sm); }
.jump a:hover { background: var(--c-surface); }
.jump a[aria-current="true"] { background: var(--c-surface); box-shadow: var(--sh-surface); color: var(--c-fg); font-weight: var(--fw-semibold); }
.period { border-top: 1px solid var(--c-border); }
.period:last-of-type { border-bottom: 1px solid var(--c-border); }
.period > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 var(--s-4); padding: var(--s-4) 0; align-items: center; }
.period > summary::-webkit-details-marker { display: none; }
.period > summary::after { content: ""; grid-column: 2; grid-row: 1 / span 3; width: 10px; height: 10px; margin-right: var(--s-2); border-right: 2px solid var(--c-fg-2); border-bottom: 2px solid var(--c-fg-2); transform: rotate(45deg); transition: transform var(--d-base) var(--d-ease); }
.period[open] > summary::after { transform: rotate(225deg); }
.period > summary:hover { background: var(--c-surface); }
.period__range { color: var(--c-fg-2); font-weight: var(--fw-semibold); }
.period__title { font-size: var(--t-lg); line-height: var(--lh-lg); color: var(--c-fg); }
.period__count { color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.period__body { display: grid; gap: var(--s-10); padding: var(--s-2) 0 var(--s-10); }
@media (min-width: 640px) {
  .period > summary { grid-template-columns: 7.5rem minmax(0, 1fr) auto auto; column-gap: var(--s-4); }
  .period > summary::after { grid-column: 4; grid-row: 1; }
  .period__count { white-space: nowrap; }
}
.role { display: grid; gap: var(--s-3); }
.role h2 { font-size: var(--t-xl); line-height: var(--lh-xl); }
.role .meta { margin-top: calc(-1 * var(--s-2)); }
.role h3 { font-size: var(--t-md); line-height: var(--lh-md); margin-top: var(--s-4); }
.role__summary { color: var(--c-fg-2); max-width: var(--w-prose); }
.role + .role { padding-top: var(--s-10); border-top: 1px solid var(--c-border); }
.more > summary { cursor: pointer; display: inline-flex; align-items: center; min-height: var(--ctl-h-touch); color: var(--c-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; font-weight: var(--fw-semibold); }
.more[open] > summary { margin-bottom: var(--s-2); }

/* ---------- 9. Project page: product layout with a spec panel ---------- */
.product { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
.product__head h1 { font-size: var(--t-h1); line-height: var(--lh-h1); }
.product__head .lede { margin-top: var(--s-3); }
.product__body > section { margin-top: var(--s-10); }
.product__body > section:first-child { margin-top: 0; }
.product__body > section > h2 { font-size: var(--t-xl); line-height: var(--lh-xl); margin-bottom: var(--s-3); }
.product__body > section > .panel__title { font-size: var(--t-lg); line-height: var(--lh-lg); }
.product__body > section > p { color: var(--c-fg-2); max-width: var(--w-prose); }
.product__body > section > p + .bullets { margin-top: var(--s-3); }
.product__specs .tags { margin-top: var(--s-1); }
.related { list-style: none; padding: 0; display: grid; gap: var(--s-4); max-width: var(--w-prose); }
.related li { display: grid; gap: var(--s-1); }
.related span { color: var(--c-fg-2); font-size: var(--t-sm); line-height: var(--lh-sm); }
@media (min-width: 1024px) {
  .product { grid-template-columns: minmax(0, 1fr) 21rem; column-gap: var(--s-12); row-gap: var(--s-10); }
  .product__head { grid-column: 1; grid-row: 1; }
  .product__specs { grid-column: 2; grid-row: 1 / span 2; align-self: start; position: sticky; top: 96px; }
  .product__body { grid-column: 1; grid-row: 2; }
}
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-6); font-size: var(--t-sm); line-height: var(--lh-sm); }
@media (min-width: 640px) { .facts { grid-template-columns: repeat(4, max-content); } }
.facts dt { color: var(--c-muted); }
.facts dd { color: var(--c-fg); }
.facts--stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-3); font-size: var(--t-body); line-height: var(--lh-body); max-width: var(--w-prose); }
.facts--stack dt { font-size: var(--t-sm); line-height: var(--lh-sm); }
.facts--stack dd { color: var(--c-fg-2); }
@media (min-width: 640px) {
  .facts--stack > div { display: grid; grid-template-columns: 12rem minmax(0, 1fr); gap: var(--s-4); }
  .facts--stack dt { font-size: inherit; line-height: inherit; }
}
.pager { display: flex; justify-content: space-between; gap: var(--s-4); margin-top: var(--s-10); padding-top: var(--s-5); border-top: 1px solid var(--c-border); }
.pager > a, .pager > span { display: grid; gap: var(--s-1); max-width: 48%; text-decoration: none; }
.pager > a span:last-child { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; font-weight: var(--fw-semibold); }
.pager > :last-child { text-align: right; justify-items: end; }

/* ---------- 10. Skills matrix ---------- */
.matrix { border-top: 1px solid var(--c-border); }
.mrow { display: grid; gap: var(--s-3); padding: var(--s-5) 0; border-bottom: 1px solid var(--c-border); scroll-margin-top: 88px; }
.mrow h3 { font-size: var(--t-lg); line-height: var(--lh-lg); }
.mrow dl { display: grid; gap: var(--s-3); }
.mrow dt { color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.mrow dd { color: var(--c-fg-2); }
.rowhead--matrix, .mrow { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) {
  .rowhead--matrix, .mrow { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.6fr) minmax(0, 1.3fr) minmax(0, 1.3fr); column-gap: var(--s-6); }
  .mrow { align-items: start; }
  .mrow h3 { font-size: var(--t-md); line-height: var(--lh-md); }
  .mrow dl { display: contents; }
  .mrow dt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .mrow dd { font-size: var(--t-md); line-height: var(--lh-md); }
}
.principles { list-style: none; padding: 0; display: grid; gap: var(--s-3); max-width: var(--w-prose); color: var(--c-fg-2); }
.principles strong { color: var(--c-fg); font-weight: var(--fw-semibold); }
.contact { display: grid; gap: var(--s-6); margin-top: var(--s-8); align-items: start; }
@media (min-width: 1024px) { .contact { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); } }

/* ---------- 11. CV page ---------- */
.cv { max-width: var(--w-reading); }
.cv__pdfbar { margin-bottom: var(--s-8); display: flex; flex-wrap: wrap; gap: var(--s-3); }
.cv__head { display: grid; gap: var(--s-2); padding-bottom: var(--s-6); border-bottom: 1px solid var(--c-border); margin-bottom: var(--s-8); }
.cv__line { color: var(--c-fg-2); font-size: var(--t-lg); line-height: var(--lh-lg); }
.cv__contact { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-5); color: var(--c-muted); font-size: var(--t-sm); line-height: var(--lh-sm); }
.cv__contact a { color: var(--c-fg-2); overflow-wrap: anywhere; }
.cv section + section, .cv-two { margin-top: var(--s-10); }
.cv h2 { font-size: var(--t-lg); line-height: var(--lh-lg); margin-bottom: var(--s-3); padding-bottom: var(--s-2); border-bottom: 1px solid var(--c-border); }
.cv .prose { color: var(--c-fg-2); max-width: var(--w-prose); }
.cv .prose + .prose { margin-top: var(--s-2); }
.cv-results { padding-left: 1.2em; display: grid; gap: var(--s-2); color: var(--c-fg-2); }
.cv-results strong, .cv-proj strong { color: var(--c-fg); font-weight: var(--fw-semibold); }
.cv-ev { color: var(--c-muted); font-size: var(--t-sm); white-space: nowrap; }
.cv-role { display: grid; gap: var(--s-1); padding: var(--s-4) 0; }
.cv-role + .cv-role { border-top: 1px solid var(--c-border); }
.cv-role__row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 0 var(--s-4); }
.cv-role__row h3 { font-size: var(--t-md); line-height: var(--lh-md); }
.cv-role__dates { color: var(--c-muted); font-size: var(--t-sm); }
.cv-role__title { color: var(--c-fg-2); }
.cv-role--condensed .cv-role__title { color: var(--c-muted); }
.cv-role ul, .cv-two ul { padding-left: 1.2em; color: var(--c-fg-2); }
.cv-role li + li { margin-top: var(--s-1); }
.cv-proj { display: grid; gap: var(--s-1); padding: var(--s-3) 0; border-top: 1px solid var(--c-border); }
.cv-proj:first-of-type { border-top: 0; }
.cv-proj span { color: var(--c-fg-2); }
.cv__more { margin-top: var(--s-3); }
.cv-two { display: grid; gap: var(--s-6); }
.cv-two section + section { margin-top: 0; }
@media (min-width: 640px) { .cv-two { grid-template-columns: 2fr 1fr; } }

/* ---------- 12. Page tails: intro prose and the closing contact line ---------- */
.page > .prose { margin-top: var(--s-3); max-width: var(--w-prose); color: var(--c-fg-2); }
.contactline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-6); }
.contactline p { max-width: var(--w-prose); color: var(--c-fg-2); }

/* ---------- 13. Footer ---------- */
.footer { background: var(--c-band); border-top: 1px solid var(--c-border); padding: var(--s-10) 0; font-size: var(--t-sm); line-height: var(--lh-sm); color: var(--c-fg-2); }
.footer__grid { display: grid; gap: var(--s-8); }
@media (min-width: 640px) { .footer__grid { grid-template-columns: 2fr 1fr 1fr; } }
.footer h2 { font-size: var(--t-md); line-height: var(--lh-md); margin-bottom: var(--s-2); }
.footer p { max-width: 52ch; }
.footer p + p { margin-top: var(--s-3); color: var(--c-muted); }
.footer ul { list-style: none; padding: 0; display: grid; gap: var(--s-1); }
.footer li a { color: var(--c-fg-2); display: inline-flex; min-height: 32px; align-items: center; }
.footer__bottom { margin-top: var(--s-8); padding-top: var(--s-4); border-top: 1px solid var(--c-border); color: var(--c-muted); }

/* ---------- 14. Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- 15. Print: the CV PDF must fit on two A4 pages ---------- */
@media print {
  @page { size: A4; margin: 12mm 14mm; }
  /* The CV prints dark ink on white paper: remap the surfaces and lift muted text to the secondary ink. */
  :root { --c-bg: var(--c-print-bg); --c-surface: var(--c-print-bg); --c-subtle: var(--c-print-bg); --c-selected: var(--c-print-bg); --c-fg: var(--c-print-fg); --c-fg-2: var(--c-print-fg-2); --c-muted: var(--c-print-fg-2); --c-border: var(--c-print-border); --c-control: var(--c-print-border); --c-link: var(--c-print-fg); --c-band: var(--c-print-bg); --c-hairline: var(--c-print-border); --c-header: var(--c-print-bg); --c-on-header: var(--c-print-fg); --c-on-header-2: var(--c-print-fg-2); }
  body { background: var(--c-print-bg); color: var(--c-print-fg); font-size: 9.5pt; line-height: 1.35; }
  .nav, .sheet, .footer, .skip, .cv__pdfbar, .btn, .cv__more, .crumbs, .tray { display: none !important; }
  .wrap { max-width: none; padding: 0; }
  .section, .section--tight { padding: 0; }
  .cv { max-width: none; }
  a { color: var(--c-print-fg); text-decoration: none; }
  .cv__head { gap: 2pt; padding-bottom: 6pt; margin-bottom: 8pt; }
  .cv__head h1 { font-size: 18pt; line-height: 1.2; }
  .cv__line { font-size: 11pt; line-height: 1.3; }
  .cv__contact { font-size: 8.5pt; gap: 2pt 10pt; }
  .cv section + section { margin-top: 9pt; }
  .cv h2 { font-size: 10.5pt; line-height: 1.3; margin-bottom: 4pt; padding-bottom: 2pt; }
  .cv .prose, .cv-results, .cv-role ul, .cv-role__title, .cv-proj, .cv-two ul, .cv-role__row h3 { font-size: 9.5pt; line-height: 1.35; }
  .cv-results { gap: 2pt; }
  .cv-ev, .cv-role__dates { font-size: 8pt; }
  .cv-role { gap: 2pt; padding: 4pt 0; }
  .cv-role li + li { margin-top: 1pt; }
  .cv-proj { padding: 3pt 0; gap: 0; }
  .cv-two { margin-top: 9pt; grid-template-columns: 2fr 1fr; gap: 12pt; }
  .cv-role, .cv-proj { break-inside: avoid; }
  details { display: block; }
  details > * { display: block; }
}
