/* Page layout for roschin.fi. Values come from tokens.css (Claude Design hand-off, 01/11/2026). */

/* Onest, self-hosted variable font (SIL Open Font License, see /fonts/OFL.txt) */
@font-face { font-family: "Onest"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../fonts/onest-cyrillic-ext.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: "Onest"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../fonts/onest-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Onest"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../fonts/onest-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: "Onest"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../fonts/onest-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; }

*, *::before, *::after { box-sizing: border-box; }

.page {
  max-width: calc(var(--content-max) + 2 * var(--gutter));
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* Header */
.site-header {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--space-4); padding-block: 14px;
}
.brand {
  display: flex; align-items: center; gap: 10px; min-height: 44px;
  text-decoration: none; font-size: 17px; font-weight: var(--weight-medium); letter-spacing: -0.01em;
}
.mark { display: block; flex: none; }
.mark-bar { fill: var(--color-text); }
.mark-accent { fill: var(--color-accent); }

.lang { display: flex; align-items: center; font-size: var(--text-small); font-weight: var(--weight-medium); }
.lang a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 6px;
  color: var(--color-text-muted); text-decoration: none;
}
.lang a:hover { color: var(--color-text); }
.lang a[aria-current="page"] { color: var(--color-text); text-decoration: underline; text-decoration-thickness: 1px; }
.lang span { color: var(--color-border-strong); }

/* Content */
main section {
  margin-top: var(--space-section);
  padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--color-border);
  display: flex; flex-direction: column; gap: var(--space-5);
}
main section.intro {
  margin-top: 0; padding-top: var(--space-intro); border-top: 0;
  gap: clamp(1.25rem, 0.975rem + 1.13vw, 1.75rem);
}
h1 {
  margin: 0; font-size: var(--text-display); line-height: var(--leading-display);
  font-weight: var(--weight-medium); letter-spacing: var(--tracking-display); text-wrap: balance;
}
h2 {
  margin: 0; font-size: var(--text-h2); line-height: var(--leading-h2);
  font-weight: var(--weight-medium); letter-spacing: var(--tracking-h2);
}
p { margin: 0; max-width: var(--measure); text-wrap: pretty; }
.lead { font-size: var(--text-lead); line-height: var(--leading-lead); letter-spacing: var(--tracking-lead); }
.list { margin-top: calc(-1 * var(--space-2)); columns: 2 21.25rem; column-gap: var(--space-6); }
.list li { text-wrap: pretty; break-inside: avoid; }
.list li:first-child { border-top: var(--border-width) solid var(--color-border); }
.nb { white-space: nowrap; }
.header-end { display: flex; align-items: center; gap: var(--space-5); }
.header-contact {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px;
  border: var(--border-width) solid var(--color-text); border-radius: var(--radius-control);
  font-size: var(--text-small); font-weight: var(--weight-medium); color: var(--color-text); text-decoration: none;
}
.header-contact:hover { background: var(--color-surface); }

/* At a glance: a summary strip, not a second list */
.facts {
  margin: var(--space-4) 0 0; padding-top: var(--space-4); border-top: var(--border-width) solid var(--color-border);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12.5rem), 1fr)); gap: var(--space-4) var(--space-5);
}
.facts > div { display: flex; flex-direction: column; gap: 4px; }
.facts dt, .facts dd { margin: 0; }
.facts dt { font-size: var(--text-small); line-height: var(--leading-small); color: var(--color-text-muted); font-weight: var(--weight-medium); }
.facts dd { font-size: var(--text-body); line-height: var(--leading-body); text-wrap: pretty; }

/* Contact */
main section.contact { gap: var(--space-6); }
.contact-lead {
  font-size: var(--text-h2); line-height: var(--leading-h2); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-h2); max-width: 40ch; text-wrap: balance;
}
.actions { display: flex; flex-wrap: wrap; gap: var(--space-3); max-width: 30rem; }
.actions .button { flex: 1 1 13.75rem; justify-content: center; }
.button { box-sizing: border-box; white-space: nowrap; }

/* Footer */
.site-footer {
  margin-top: var(--space-section);
  border-top: var(--border-width) solid var(--color-border);
  padding-block: var(--space-5) 40px;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  font-size: var(--text-small); line-height: var(--leading-small); color: var(--color-text-muted);
}
.site-footer a { color: var(--color-text-muted); white-space: nowrap; }
.footer-name { color: var(--color-text); font-weight: var(--weight-medium); }

@media (max-width: 37.5rem) { .site-footer > :first-child { flex: 1 0 100%; } }
.brand span { white-space: nowrap; }
@media (max-width: 37.5rem) {
  .site-header { gap: var(--space-2); }
  .header-end { gap: var(--space-2); }
  .header-contact { padding: 0 12px; }
}
@media (max-width: 23.75rem) { .brand span { white-space: normal; } }

/* Text sections: heading left, text beside it on wide screens */
.split .body { display: flex; flex-direction: column; gap: var(--space-5); }
@media (min-width: 52rem) {
  main section.split { display: grid; grid-template-columns: 15rem minmax(0, 1fr); column-gap: var(--space-6); align-items: start; }
}

/* Portrait: under the About heading on wide screens, above the text on phones */
.portrait {
  width: 160px; height: 160px; object-fit: cover; object-position: center 25%;
  border: var(--border-width) solid var(--color-border); border-radius: var(--radius-control);
}
@media (min-width: 52rem) {
  main section.about-section { grid-template-areas: "heading body" "photo body"; grid-template-rows: auto 1fr; row-gap: var(--space-5); }
  .about-section h2 { grid-area: heading; }
  .about-section .portrait { grid-area: photo; }
  .about-section .body { grid-area: body; }
}
@media (max-width: 37.5rem) { .portrait { width: 112px; height: 112px; } }

/* Hero call button keeps its natural width */
.hero-actions { max-width: none; }
.hero-actions .button { flex: 0 0 auto; }
/* 404 page: second language block sits lower and quieter */
main section.nf-ru { margin-top: var(--space-6); padding-top: var(--space-5); border-top: var(--border-width) solid var(--color-border); }
main section.nf-ru h2 { font-size: var(--text-h2); }
@media (max-width: 23.75rem) { .hero-actions .button { white-space: normal; text-align: center; flex: 1 1 auto; padding-block: 10px; line-height: 1.25; } }

/* Sticky header: the Contact button stays reachable while scrolling */
.site-header {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--color-bg) 97%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px); backdrop-filter: saturate(1.4) blur(10px);
}
main section.contact { scroll-margin-top: 5.5rem; }

/* Small transitions, off when the system asks for reduced motion */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  a, .button, .header-contact { transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, text-decoration-thickness 150ms ease; }
}

/* Header hairline appears once the page scrolls (scroll-driven, no JavaScript, only where supported) */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes header-line { from { box-shadow: 0 1px 0 transparent; } to { box-shadow: 0 1px 0 var(--color-border); } }
    .site-header { animation: header-line linear both; animation-timeline: scroll(root block); animation-range: 0 80px; }
  }
}

/* Sections fade in by 12 px as they enter the screen (CSS only, only where supported, never in print) */
@supports (animation-timeline: view()) {
  @media screen and (prefers-reduced-motion: no-preference) {
    @keyframes reveal { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
    main section:not(.intro) { animation: reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 40%; }
  }
}

/* The price figure in the summary strip reads first */
.facts .figure { font-size: 1.2em; font-weight: var(--weight-medium); }

/* Print: plain black on white, no sticky header, no buttons, nothing animated or hidden */
@media print {
  :root:root:root { --color-bg: #FFFFFF; --color-surface: #F6F5F2; --color-border: #CFCDC7; --color-border-strong: #8D8B85; --color-text-muted: #5E5C57; --color-text: #161614; color-scheme: light; }
  body { background: #FFFFFF; color: #161614; }
  .site-header { position: static; background: none; backdrop-filter: none; -webkit-backdrop-filter: none; animation: none; box-shadow: none; }
  .header-contact, .hero-actions, .lang { display: none; }
  main section, main section:not(.intro) { animation: none; opacity: 1; transform: none; break-inside: avoid; margin-top: 1.5rem; padding-top: 1rem; }
  main section.intro { padding-top: 1rem; }
  .list li::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* How it works: four steps on one line, each marked with the same bar as the list */
.steps {
  list-style: none; margin: calc(-1 * var(--space-2)) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12.5rem), 1fr)); gap: var(--space-5);
}
.steps li { position: relative; padding-top: var(--space-4); border-top: var(--border-width) solid var(--color-border); display: flex; flex-direction: column; gap: 4px; }
.steps li::before { content: ""; position: absolute; left: 0; top: -2px; width: 12px; height: 3px; background: var(--color-text); }
.step-title { font-weight: var(--weight-medium); }
.step-text { color: var(--color-text-muted); text-wrap: pretty; }
@media print { .steps li::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }

/* Small muted privacy note under the hero button */
.note { font-size: var(--text-small); line-height: var(--leading-small); color: var(--color-text-muted); max-width: 46ch; margin-top: calc(-1 * var(--space-2)); }
@media print { .note { display: none; } }

/* 404: the logo mark with its terracotta bar wandered off, leaving a dashed outline where it belongs */
.lost { display: block; margin-bottom: var(--space-4); overflow: visible; }
.lost-slot { fill: none; stroke: var(--color-border-strong); stroke-width: 0.12; stroke-dasharray: 0.5 0.4; }
.lost-bar { transform-box: fill-box; transform-origin: center; transform: translate(16px, -0.8px) rotate(-8deg); }
@media (prefers-reduced-motion: no-preference) {
  .lost-bar { animation: wander 5s ease-in-out infinite alternate; }
  @keyframes wander { from { transform: translate(16px, -0.8px) rotate(-8deg); } to { transform: translate(17.4px, 0.6px) rotate(-3deg); } }
}
@media print { .lost { display: none; } }

/* Touch 1: hovering or focusing the brand slides the terracotta bar of the mark into line with the others.
   Only for people who have not asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .brand .mark-accent { transform-box: fill-box; transition: transform 260ms cubic-bezier(.3, .7, .2, 1); }
  .brand:hover .mark-accent, .brand:focus-visible .mark-accent { transform: translateX(-5px); }
}

/* Touch 2: hovering a step draws its marker bar across the full step in the accent colour.
   Hover only, and only on devices that really hover, so touch screens never get a stuck state. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .steps li::before { transition: width 320ms cubic-bezier(.3, .7, .2, 1), background-color 200ms ease; }
  .steps li:hover::before { width: 100%; background: var(--color-accent); }
}
