/*
 * Styles for hejpetr.cz — one file for every page.
 *
 * Order: design tokens (colours, fonts, spacing), fonts, base styles and buttons, then the
 * parts of the pages in the order they appear on the site. Change colours, fonts and spacing
 * only in the tokens at the top, never directly in the rules below.
 */

/* ==========================================================================
   Design tokens
   ========================================================================== */

/*
 * Design tokens — the only place where raw values live.
 * Palette: brief 4.2. Components use the semantic layer (--fg, --accent…) at the bottom,
 * which surfaces (.mat, .card) remap, so one component looks right on paper, mat and card.
 */

:root {
  /* Palette — light mode (default) */
  --color-mat: #16323a;
  --color-mat-deep: #0f2328;
  --color-paper: #ffffff;
  --color-surface-alt: #f3f5f6;
  --color-ink: #12262c;
  --color-ink-muted: #5a6670;
  --color-rule: #dde2e5;
  --color-field-border: #7a878e;
  --color-red: #c8102e;
  --color-red-hover: #a60d26;
  --color-on-red: #ffffff;
  --color-on-mat: #f3f5f6;
  --color-on-mat-muted: #a9bac0;
  --color-focus: #c8102e;
  --color-focus-on-mat: #ffffff;

  /* The mat looks identical in both modes, so its button colours never switch. */
  --mat-red: #c8102e;
  --mat-red-hover: #a60d26;
  --mat-on-red: #ffffff;
  /* Hides the page under the open mobile menu: the deep mat shade, nearly opaque, over a blur. */
  --menu-backdrop: rgb(15 35 40 / 0.92);
  --menu-backdrop-blur: 6px;

  /* The playing card is a physical object: dark mode never touches these. */
  --card-paper: #ffffff;
  --card-ink: #12262c;
  --card-red: #c8102e;
  --card-edge: #d9dee1;
  --floating-shadow: 0 2px 4px rgb(0 0 0 / 0.2), 0 8px 24px -4px rgb(0 0 0 / 0.35);
  --card-shadow:
    0 1px 1px rgb(0 0 0 / 0.25), 0 12px 24px -6px rgb(0 0 0 / 0.45),
    0 30px 60px -12px rgb(0 0 0 / 0.35);

  /* Typography */
  --font-display:
    'Bricolage Grotesque Variable', 'Bricolage Fallback', 'Bricolage Fallback Roboto', sans-serif;
  --font-display-condensed:
    'Bricolage Grotesque Variable', 'Bricolage Fallback Condensed',
    'Bricolage Fallback Condensed Roboto', sans-serif;
  --font-text:
    'Source Sans 3 Variable', 'Source Sans Fallback', 'Source Sans Fallback Roboto', sans-serif;

  --text-h1: clamp(2.5rem, 1.25rem + 4.5vw, 5rem);
  --text-h2: clamp(1.875rem, 1.25rem + 2vw, 2.75rem);
  --text-h3: 1.375rem;
  --text-lead: 1.25rem;
  --text-body: 1.0625rem;
  --text-small: 0.9375rem;
  --text-label: 1rem;
  --text-button: 1.0625rem;
  --text-price: 1.75rem;
  --text-step: 3rem;
  --text-step-dot: 1.75rem;

  --leading-h1: 0.95;
  --leading-h2: 1.05;
  --leading-h3: 1.2;
  --leading-lead: 1.5;
  --leading-body: 1.6;
  --leading-small: 1.5;
  --leading-label: 1.4;

  /* Font widths map onto the Bricolage `wdth` axis. */
  --stretch-h1: 78%;
  --stretch-h2: 85%;
  --stretch-step: 75%;

  /*
   * Line measures in em rather than ch: `ch` follows the zero of whichever font is
   * currently rendered, so it would change when the web font replaces the fallback.
   * 16ch of Bricolage 750/78 ≈ 7.6em; 60ch and 68ch of Source Sans 3 ≈ 30em and 34em.
   */
  --measure-h1: 7.6em;
  --measure-lead: 30em;
  --measure-body: 34em;

  /* Spacing scale */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  /* Layout */
  --container-max: 72rem;
  --gutter: clamp(1rem, 0.5rem + 2vw, 2rem);
  --grid-gap: var(--space-5);
  --section-space: clamp(4rem, 3rem + 4vw, 8rem);
  --hero-space: clamp(3rem, 2rem + 4vw, 6rem);
  --header-height: 4rem;
  --control-height: 3rem;
  --control-height-compact: 2rem;
  --step-dot: 3.5rem;

  /* Shape — radius by role (brief 4.10) */
  --radius-control: 6px;
  --radius-image: 4px;
  --rule-width: 1px;
  --border-control: 2px;

  /* Focus */
  --focus-width: 3px;
  --focus-offset: 2px;
  --focus-offset-card: 6px;

  /* Motion */
  --ease-card: cubic-bezier(0.2, 0.7, 0.2, 1);
  --duration-reveal: 800ms;
  --delay-reveal: 250ms;
  --duration-flip: 600ms;
  --duration-menu: 150ms;
  --duration-hover: 120ms;

  /* Semantic layer — paper surface */
  --surface: var(--color-paper);
  --fg: var(--color-ink);
  --fg-muted: var(--color-ink-muted);
  --accent: var(--color-red);
  --accent-hover: var(--color-red-hover);
  --on-accent: var(--color-on-red);
  --focus-ring: var(--color-focus);
  --rule: var(--color-rule);

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-paper: #0f2328;
    --color-surface-alt: #16323a;
    --color-ink: #eef2f3;
    --color-ink-muted: #a9bac0;
    --color-rule: #2a4a53;
    --color-field-border: #6f8a92;
    --color-red: #ff5a6a;
    --color-red-hover: #ff7a87;
    --color-on-red: #0f2328;
    --color-focus: #ff5a6a;
  }
}

@media (min-width: 768px) {
  :root {
    --text-h3: 1.5rem;
    --text-body: 1.125rem;
  }
}

/* Mat surface: header, hero, footer. Same in light and dark mode. */
.mat {
  --surface: var(--color-mat);
  --fg: var(--color-on-mat);
  --fg-muted: var(--color-on-mat-muted);
  --accent: var(--mat-red);
  --accent-hover: var(--mat-red-hover);
  --on-accent: var(--mat-on-red);
  --focus-ring: var(--color-focus-on-mat);
  --rule: var(--color-mat-deep);

  background-color: var(--surface);
  color: var(--fg);
}

/* ==========================================================================
   Fonts
   ========================================================================== */

/*
 * Self-hosted fonts, generated from Fontsource by scripts/generate-fonts.mjs. Czech needs two
 * files per family (á é í ó ú ý and punctuation in `latin`, č ď ě ň ř š ť ů ž in `latin-ext`),
 * each trimmed to the characters Czech and Slovak text uses and to the weights the site uses.
 * unicode-range must match scripts/lib/font-subsets.mjs; tests/unit/fonts.test.ts checks it.
 */

/* Bricolage Grotesque — wght 600–800, wdth 75–100, opsz 12–96 */
@font-face {
  font-family: 'Bricolage Grotesque Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 600 800;
  font-stretch: 75% 100%;
  src: url('../fonts/bricolage-grotesque-latin-ext.woff2') format('woff2');
  unicode-range:
    U+010C-010F, U+011A-011B, U+0139-013A, U+013D-013E, U+0147-0148, U+0154-0155, U+0158-0159,
    U+0160-0161, U+0164-0165, U+016E-016F, U+017D-017E;
}

@font-face {
  font-family: 'Bricolage Grotesque Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 600 800;
  font-stretch: 75% 100%;
  src: url('../fonts/bricolage-grotesque-latin.woff2') format('woff2');
  unicode-range:
    U+0020-007E, U+00A0, U+00A7, U+00A9, U+00AB, U+00B0, U+00BB, U+00C1, U+00C4, U+00C9, U+00CD,
    U+00D3-00D4, U+00D7, U+00DA, U+00DD, U+00E1, U+00E4, U+00E9, U+00ED, U+00F3-00F4, U+00FA,
    U+00FD, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+20AC;
}

/* Source Sans 3 — wght 400–600 */
@font-face {
  font-family: 'Source Sans 3 Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 400 600;
  src: url('../fonts/source-sans-3-latin-ext.woff2') format('woff2');
  unicode-range:
    U+010C-010F, U+011A-011B, U+0139-013A, U+013D-013E, U+0147-0148, U+0154-0155, U+0158-0159,
    U+0160-0161, U+0164-0165, U+016E-016F, U+017D-017E;
}

@font-face {
  font-family: 'Source Sans 3 Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 400 600;
  src: url('../fonts/source-sans-3-latin.woff2') format('woff2');
  unicode-range:
    U+0020-007E, U+00A0-00A3, U+00A5-00AC, U+00AE-00FF, U+2013-2014, U+2018-201A, U+201C-201E,
    U+2022, U+2026, U+20AC;
}

/*
 * Metric-matched local fallbacks, so swapping in the web fonts does not shift the layout.
 * size-adjust = measured width ratio of real site texts (fontTools); the overrides are the web
 * font's typo metrics divided by size-adjust. Values and method: docs/design.md 1.4.
 * Arial and Liberation Sans share metrics; Roboto covers Android.
 */

/* H1 and step numbers (wdth 75–78). Ratio measured at the mobile H1 size (40px, opsz 40). */
@font-face {
  font-family: 'Bricolage Fallback Condensed';
  font-weight: 100 900;
  src:
    local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'),
    local('LiberationSans-Bold');
  size-adjust: 80%;
  ascent-override: 116.25%;
  descent-override: 33.75%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Bricolage Fallback Condensed Roboto';
  font-weight: 100 900;
  src: local('Roboto Bold'), local('Roboto-Bold');
  size-adjust: 84.7%;
  ascent-override: 109.8%;
  descent-override: 31.88%;
  line-gap-override: 0%;
}

/* H2, H3, prices, the name in the logo. */
@font-face {
  font-family: 'Bricolage Fallback';
  font-weight: 100 900;
  src:
    local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'),
    local('LiberationSans-Bold');
  size-adjust: 88%;
  ascent-override: 105.68%;
  descent-override: 30.68%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Bricolage Fallback Roboto';
  font-weight: 100 900;
  src: local('Roboto Bold'), local('Roboto-Bold');
  size-adjust: 93%;
  ascent-override: 100%;
  descent-override: 29.03%;
  line-gap-override: 0%;
}

/* Body text (400) and UI text (600). */
@font-face {
  font-family: 'Source Sans Fallback';
  font-weight: 100 500;
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('LiberationSans');
  size-adjust: 93.3%;
  ascent-override: 109.75%;
  descent-override: 42.87%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Source Sans Fallback';
  font-weight: 600 900;
  src:
    local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'),
    local('LiberationSans-Bold');
  size-adjust: 89.7%;
  ascent-override: 114.16%;
  descent-override: 44.59%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Source Sans Fallback Roboto';
  font-weight: 100 500;
  src: local('Roboto'), local('Roboto-Regular');
  size-adjust: 94.1%;
  ascent-override: 108.82%;
  descent-override: 42.51%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Source Sans Fallback Roboto';
  font-weight: 600 900;
  src: local('Roboto Bold'), local('Roboto-Bold');
  size-adjust: 95.4%;
  ascent-override: 107.34%;
  descent-override: 41.93%;
  line-gap-override: 0%;
}

/* ==========================================================================
   Base styles
   ========================================================================== */

/* Base styles: reset, typography, layout primitives, buttons. Values come from tokens.css. */

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

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Keeps anchored headings and focused elements clear of the sticky header. */
  scroll-padding-block-start: calc(var(--header-height) + var(--space-5));
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  min-block-size: 100vh;
  background-color: var(--color-paper);
  color: var(--fg);
  font-family: var(--font-text);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
picture,
svg {
  display: block;
  max-inline-size: 100%;
}

img {
  block-size: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  text-wrap: balance;
  overflow-wrap: break-word;
}

h1 {
  font-family: var(--font-display-condensed);
  font-size: var(--text-h1);
  font-weight: 750;
  font-stretch: var(--stretch-h1);
  line-height: var(--leading-h1);
  letter-spacing: -0.015em;
  max-inline-size: var(--measure-h1);
}

h2 {
  font-size: var(--text-h2);
  font-weight: 700;
  font-stretch: var(--stretch-h2);
  line-height: var(--leading-h2);
}

h3 {
  font-size: var(--text-h3);
  font-weight: 650;
  line-height: var(--leading-h3);
}

p,
li,
dd {
  text-wrap: pretty;
  overflow-wrap: break-word;
}

p {
  max-inline-size: var(--measure-body);
}

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* `<main tabindex="-1">` receives focus from the skip link; it needs no ring of its own. */
[tabindex='-1']:focus:not(:focus-visible) {
  outline: none;
}

/* Layout primitives */

.container {
  inline-size: min(100% - 2 * var(--gutter), var(--container-max));
  margin-inline: auto;
}

.visually-hidden:not(:focus, :active) {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Skip link: first focusable element, visible only when focused. */
.skip-link {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-control);
  background-color: var(--color-paper);
  color: var(--color-ink);
  font-weight: 600;
  translate: 0 calc(-100% - var(--space-4));
}

.skip-link:focus-visible {
  translate: 0 0;
  outline-color: var(--color-focus);
}

/* Buttons */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--control-height);
  padding-inline: 1.25rem;
  border: var(--border-control) solid transparent;
  border-radius: var(--radius-control);
  font-family: var(--font-text);
  font-size: var(--text-button);
  font-weight: 600;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--duration-hover) ease-out,
    border-color var(--duration-hover) ease-out,
    color var(--duration-hover) ease-out;
}

.button--primary {
  background-color: var(--accent);
  color: var(--on-accent);
}

.button--secondary {
  border-color: currentcolor;
  background-color: transparent;
  color: var(--fg);
}

/* Touch screens keep :hover on a tapped button until the next tap elsewhere, which left the
   closed Menu button looking pressed; only real pointers get the hover fill. */
@media (hover: hover) {
  .button--primary:hover {
    background-color: var(--accent-hover);
  }

  .button--secondary:hover {
    background-color: var(--fg);
    border-color: var(--fg);
    color: var(--surface);
  }
}

/* Reduced motion: the only place where !important is allowed (brief 11). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0s !important;
    animation-delay: 0s !important;
    transition-duration: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
}

.site-header__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: var(--space-5);
  min-block-size: var(--header-height);
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--control-height);
  color: var(--fg);
  font-weight: 600;
  text-decoration: none;
}

.site-nav__link:hover {
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
}

@media (min-width: 1024px) {
  .menu-button {
    display: none;
  }

  .site-menu {
    display: flex;
    align-items: center;
    gap: var(--space-6);
  }
}

/*
 * Below 1024 px the menu collapses behind the Menu button. The collapsed layout applies from
 * the first paint whenever scripting is enabled, so nothing shifts when menu.ts starts;
 * `scripting: none` (JavaScript off) gets the plain, always visible menu instead.
 */
@media (max-width: 1023.98px) {
  /* The open panel lies over the hero, which is the same mat colour, so it takes the deeper
     mat shade to read as a separate layer. */
  .site-menu {
    display: none;
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    padding: var(--space-2) var(--gutter) var(--space-6);
    background-color: var(--color-mat-deep);
  }

  .menu-button[aria-expanded='true'] {
    border-color: var(--fg);
    background-color: var(--fg);
    color: var(--surface);
  }

  .site-menu[data-open] {
    display: block;
    opacity: 1;
    translate: 0 0;
    transition:
      opacity var(--duration-menu) ease-out,
      translate var(--duration-menu) ease-out;
  }

  @starting-style {
    .site-menu[data-open] {
      opacity: 0;
      translate: 0 calc(-1 * var(--space-1));
    }
  }

  .site-nav {
    flex-direction: column;
    gap: 0;
  }

  .site-nav__link {
    inline-size: 100%;
    font-size: var(--text-lead);
  }

  .site-menu__cta {
    inline-size: 100%;
    margin-block-start: var(--space-4);
  }

  /* While the menu is open, the page below the header is dimmed so the menu is all that
     stands out. The layer belongs to the header, so menu.js treats a tap on it as outside. */
  .site-header:has(.site-menu[data-open])::after {
    content: '';
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    z-index: -1;
    block-size: 100dvh;
    background-color: var(--menu-backdrop);
    backdrop-filter: blur(var(--menu-backdrop-blur));
    opacity: 1;
    transition: opacity var(--duration-menu) ease-out;
  }

  @starting-style {
    .site-header:has(.site-menu[data-open])::after {
      opacity: 0;
    }
  }
}

/* Without JavaScript the whole menu stays visible. A tall sticky header would then cover the
   page, so it scrolls away with the content. */
@media (max-width: 1023.98px) and (scripting: none) {
  .site-header {
    position: relative;
  }

  .menu-button {
    display: none;
  }

  .site-menu {
    display: flex;
    position: static;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-5);
    inline-size: 100%;
    padding: 0 0 var(--space-4);
    background-color: transparent;
  }

  .site-nav {
    flex-direction: row;
    gap: var(--space-1) var(--space-5);
  }

  .site-nav__link {
    inline-size: auto;
    font-size: inherit;
  }

  .site-menu__cta {
    inline-size: auto;
    margin-block-start: 0;
  }
}

/* ==========================================================================
   Logo
   ========================================================================== */

.logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--control-height);
  color: var(--fg);
  text-decoration: none;
}

.logo__mark {
  display: flex;
  font-size: 2.25rem;
}

.logo__name {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.1;
  white-space: nowrap;
}

.logo:hover .logo__name {
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

/* ==========================================================================
   Card index „M" above ♠ (logo, card corners)
   ========================================================================== */

.index-mark {
  block-size: 1em;
  inline-size: auto;
  aspect-ratio: 100 / 144;
  fill: var(--fg);
  flex: none;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding-block: var(--space-8) var(--space-6);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-6);
}

.site-footer__identity {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.site-footer__mark {
  display: flex;
  font-size: 2.75rem;
}

.site-footer__name {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 650;
  line-height: var(--leading-h3);
}

.site-footer__tagline,
.site-footer__legal,
.site-footer__bottom {
  color: var(--fg-muted);
}

.site-footer__bottom {
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-5);
  border-block-start: var(--rule-width) solid var(--rule);
}

.site-footer__links ul {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Links sit on their own lines, so they get the full 24 px target height (WCAG 2.5.8).
   The e-mail link keeps its plain inline box, as it always has. */
.site-footer__links a:not(.email-link) {
  display: inline-block;
  padding-block: var(--space-1);
}

@media (min-width: 768px) {
  .site-footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .site-footer__grid {
    grid-template-columns: 4fr 5fr 3fr;
    column-gap: var(--space-7);
  }
}

/* ==========================================================================
   Suit symbols ♠ ♦ ♣ ♥
   ========================================================================== */

/* Sized by the surrounding font size; the colour follows the surface (paper, mat, card). */
.suit {
  inline-size: 1em;
  block-size: 1em;
  flex: none;
  fill: currentcolor;
}

.suit--spade,
.suit--club {
  color: var(--fg);
}

.suit--diamond,
.suit--heart {
  color: var(--accent);
}

/* ==========================================================================
   Floating enquiry button
   ========================================================================== */

/*
 * On phones and tablets "Napsat poptávku" hides in the collapsed menu, so once the hero's
 * button scrolls away a copy floats in the bottom right corner. menu.js shows it
 * (data-visible) and hides it again at the contact form and in the footer. Desktop keeps the
 * button in the sticky header instead. It sits below the header, so the open menu's backdrop
 * covers it too.
 */
.floating-cta {
  position: fixed;
  inset-block-end: max(var(--space-4), env(safe-area-inset-bottom));
  inset-inline-end: var(--gutter);
  z-index: 40;
  box-shadow: var(--floating-shadow);
  visibility: hidden;
  opacity: 0;
  translate: 0 var(--space-3);
  transition:
    opacity var(--duration-menu) ease-out,
    translate var(--duration-menu) ease-out,
    visibility 0s linear var(--duration-menu),
    background-color var(--duration-hover) ease-out;
}

.floating-cta[data-visible] {
  visibility: visible;
  opacity: 1;
  translate: 0 0;
  transition:
    opacity var(--duration-menu) ease-out,
    translate var(--duration-menu) ease-out,
    visibility 0s,
    background-color var(--duration-hover) ease-out;
}

@media (min-width: 1024px), (scripting: none) {
  .floating-cta {
    display: none;
  }
}

/* ==========================================================================
   E-mail link
   ========================================================================== */

/* Addresses have no spaces to break at; let them wrap anywhere on narrow screens. */
.email-link {
  overflow-wrap: anywhere;
}

/* ==========================================================================
   Home page sections (heading, lead, dividing rule)
   ========================================================================== */

/* Sections are separated by space and a thin rule halfway, never by coloured bands
   (brief 4.4): the section spacing is the distance between two sections' contents. */
.section {
  padding-block: calc(var(--section-space) / 2);
}

.section + .section > .container {
  padding-block-start: calc(var(--section-space) / 2);
  border-block-start: var(--rule-width) solid var(--rule);
}

.section + .section {
  padding-block-start: 0;
}

/* Next to the mat or the footer a full step of space, as there is no rule to share it. */
.section:not(.section + .section) {
  padding-block-start: var(--section-space);
}

.section:last-child {
  padding-block-end: var(--section-space);
}

.section__header {
  margin-block-end: var(--space-7);
}

.section__title {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  column-gap: 0.3em;
}

.section__title .section__suit {
  inline-size: 0.7em;
  block-size: 0.7em;
  align-self: center;
}

.section__lead {
  margin-block-start: var(--space-4);
  max-inline-size: var(--measure-lead);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

/* ==========================================================================
   Hero („Weby a interní systémy…")
   ========================================================================== */

.hero {
  padding-block: var(--hero-space);
}

.hero__grid {
  display: grid;
  gap: var(--space-8);
}

.hero__lead {
  margin-block-start: var(--space-5);
  max-inline-size: var(--measure-lead);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.hero__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-block-start: var(--space-6);
}

.hero__note {
  margin-block-start: var(--space-4);
  color: var(--fg-muted);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

/* The card is an object on the mat: aligned to the start like everything else, with a small
   inset so its rotation does not read as a misalignment. */
.hero__card {
  padding-inline-start: var(--space-4);
}

@media (min-width: 480px) {
  .hero__actions {
    flex-direction: row;
    flex-wrap: wrap;
  }
}

@media (min-width: 1024px) {
  .hero__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: center;
  }

  .hero__text {
    grid-column: 1 / span 7;
  }

  .hero__card {
    grid-column: 9 / span 4;
    justify-self: end;
    padding-inline-start: 0;
  }
}

/* ==========================================================================
   Playing card in the hero
   ========================================================================== */

.hero-card {
  /* Card geometry is intrinsic to the object, so it lives here rather than in tokens. */
  --card-w: clamp(13rem, 24vw, 21rem);
  --card-radius: calc(var(--card-w) * 0.048);

  inline-size: var(--card-w);
  aspect-ratio: 5 / 7;
  perspective: 1200px;
  rotate: -3deg;
  animation: hero-card-deal var(--duration-reveal) var(--ease-card) var(--delay-reveal) both;
}

@media (max-width: 1023.98px) {
  .hero-card {
    --card-w: min(clamp(13rem, 24vw, 21rem), 15rem);
  }
}

.card {
  position: relative;
  display: block;
  inline-size: 100%;
  block-size: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--card-radius);
  background: none;
  color: inherit;
  font: inherit;
  transform-style: preserve-3d;
  container-type: inline-size;
  cursor: default;
  -webkit-tap-highlight-color: transparent;
}

/* Without JS the button stays disabled; it must look exactly like the enabled card. */
.card:disabled {
  opacity: 1;
  color: inherit;
}

.card:enabled {
  cursor: pointer;
}

.card:focus-visible {
  outline: var(--focus-width) solid var(--color-focus-on-mat);
  outline-offset: var(--focus-offset-card);
}

/* Reveal and click-flip run on different elements: an animation with fill-mode `both`
   would otherwise keep overriding the transform set by the flip. */
.card__reveal,
.card__flip {
  position: absolute;
  inset: 0;
  display: block;
  transform-style: preserve-3d;
}

.card__reveal {
  animation: hero-card-reveal var(--duration-reveal) var(--ease-card) var(--delay-reveal) both;
}

.card__flip {
  transition: transform var(--duration-flip) var(--ease-card);
}

.card.is-flipped .card__flip {
  transform: rotateY(180deg);
}

.card__face {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.card__face--front {
  /* The card is a physical object: its ink never follows the page's dark mode. */
  --fg: var(--card-ink);
  --accent: var(--card-red);

  border: var(--rule-width) solid var(--card-edge);
  background-color: var(--card-paper);
}

.card__face--back {
  transform: rotateY(180deg);
  background-color: var(--card-red);
}

/* Sizes below are in cqi — percent of the card width — like a printed card. */
.card__art {
  position: absolute;
  inset: 7cqi;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: var(--rule-width) solid var(--card-ink);
  background-color: var(--card-paper);
}

.card__art picture,
.card__art img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}

.card__art img {
  object-fit: cover;
  object-position: 50% 20%;
}

.card__placeholder {
  inline-size: 60%;
  fill: var(--card-ink);
}

.card__corner {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.card__corner--end {
  rotate: 180deg;
}

/* The frame bends around the index, like on cards with full-bleed artwork. */
.card__notch {
  position: absolute;
  inset-block-start: calc(7cqi - var(--rule-width));
  inset-inline-start: calc(7cqi - var(--rule-width));
  inline-size: calc(11.5cqi + var(--rule-width));
  block-size: calc(20.5cqi + var(--rule-width));
  border-inline-end: var(--rule-width) solid var(--card-ink);
  border-block-end: var(--rule-width) solid var(--card-ink);
  background-color: var(--card-paper);
}

/* Index height 21.3cqi gives an M with a cap height of 11 % of the card width. */
.card__index {
  position: absolute;
  inset-block-start: 4cqi;
  inset-inline-start: 3.2cqi;
  display: flex;
  font-size: 21.3cqi;
}

@keyframes hero-card-reveal {
  from {
    transform: rotateY(180deg);
  }

  to {
    transform: rotateY(0deg);
  }
}

@keyframes hero-card-deal {
  from {
    translate: 0 12px;
    rotate: -6deg;
  }

  to {
    translate: 0 0;
    rotate: -3deg;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-card,
  .card__reveal {
    animation: none;
  }

  .card__flip {
    transition: none;
  }
}

/* ==========================================================================
   Card back
   ========================================================================== */

.card-back {
  inline-size: 100%;
  block-size: 100%;
}

.card-back__field {
  fill: var(--card-red);
}

.card-back__line {
  fill: none;
  stroke: var(--card-paper);
  stroke-width: 0.8;
  opacity: 0.55;
}

.card-back__frame {
  fill: none;
  stroke: var(--card-paper);
  stroke-width: 2.5;
}

.card-back__oval {
  fill: var(--card-red);
  stroke: var(--card-paper);
  stroke-width: 2.5;
}

.card-back__oval-inner {
  fill: none;
  stroke: var(--card-paper);
  stroke-width: 1;
}

.card-back__monogram {
  fill: var(--card-paper);
}

/* ==========================================================================
   Services („Co pro vás udělám")
   ========================================================================== */

.pillars {
  display: grid;
  gap: var(--space-8);
}

.pillar .pillar__suit {
  inline-size: 2rem;
  block-size: 2rem;
}

.pillar__title {
  margin-block-start: var(--space-4);
  padding-block-end: var(--space-4);
  border-block-end: var(--rule-width) solid var(--rule);
}

.pillar__text {
  margin-block-start: var(--space-4);
}

.pillar__items {
  margin-block-start: var(--space-4);
  padding-inline-start: 1.1em;
}

.pillar__items li + li {
  margin-block-start: var(--space-1);
}

.pillar__items li::marker {
  color: var(--fg-muted);
}

@media (min-width: 1024px) {
  .pillars {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--space-7);
  }
}

/* ==========================================================================
   About („O mně")
   ========================================================================== */

.about {
  display: grid;
  gap: var(--space-7);
}

.about__text p + p {
  margin-block-start: var(--space-4);
}

.about__facts {
  margin: 0;
}

.about__fact {
  padding-block: var(--space-4);
  border-block-start: var(--rule-width) solid var(--rule);
}

.about__fact:last-child {
  border-block-end: var(--rule-width) solid var(--rule);
}

.about__fact dt {
  font-weight: 600;
}

.about__fact dd {
  margin: var(--space-1) 0 0;
  color: var(--fg-muted);
}

@media (min-width: 1024px) {
  .about {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: start;
  }

  .about__text {
    grid-column: 1 / span 7;
  }

  .about__facts {
    grid-column: 8 / span 5;
  }
}

/* ==========================================================================
   Projects („Na čem jsem pracoval")
   ========================================================================== */

.projects {
  margin: 0;
  padding: 0;
  list-style: none;
  container-type: inline-size;
}

.project {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--space-6);
  border-block-start: var(--rule-width) solid var(--rule);
}

/* <Picture> puts the class on the <img>. */
.project img.project__image {
  display: block;
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border: var(--rule-width) solid var(--rule);
  border-radius: var(--radius-image);
}

/* The title and the picture link to the project too. The title keeps its heading look and
   is underlined only on hover; the picture is a plain block without any hover effect. */
.project__title a {
  color: inherit;
  text-decoration: none;
}

.project__title a:hover {
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
}

.project__image-link {
  display: block;
}

.project__role {
  margin-block-start: var(--space-1);
  color: var(--fg-muted);
}

.project__details {
  margin-block-start: var(--space-4);
}

.project__tech {
  margin-block-start: var(--space-3);
  color: var(--fg-muted);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.project__link {
  margin-block-start: var(--space-4);
  font-weight: 600;
}

@container (min-width: 48rem) {
  .project--with-image {
    grid-template-columns: 5fr 7fr;
    column-gap: var(--space-7);
    align-items: start;
  }

  /* Without a picture the name takes the picture's column, so the row still reads as a row
     and no empty frame is left behind. */
  .project:not(.project--with-image) .project__body {
    display: grid;
    grid-template-columns: 5fr 7fr;
    column-gap: var(--space-7);
  }

  .project:not(.project--with-image) .project__details {
    margin-block-start: 0;
  }
}

/* ==========================================================================
   Process („Jak spolupráce probíhá")
   ========================================================================== */

.steps {
  display: grid;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  column-gap: var(--space-4);
}

.step__number {
  font-family: var(--font-display-condensed);
  font-size: var(--text-step);
  font-weight: 800;
  font-stretch: var(--stretch-step);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.step__title {
  padding-block-start: var(--space-2);
}

.step__text {
  margin-block-start: var(--space-2);
}

/* Five steps fit one row only from 1100 px (brief 4.5). Step titles stay on one line: a column
   grows to fit its title ("Úvodní konzultace") and the others give up the few pixels. */
@media (min-width: 1100px) {
  .steps {
    grid-template-columns: repeat(5, minmax(min-content, 1fr));
    column-gap: var(--space-5);
  }

  /* A timeline: each number sits in a ring centred over its step; the rings are filled with
     the page colour, so the thin rule joining them runs only between them. */
  .steps {
    isolation: isolate;
  }

  .step {
    position: relative;
    grid-template-columns: minmax(min-content, 1fr);
    align-content: start;
    justify-items: center;
    text-align: center;
  }

  .step:not(:last-child)::before {
    content: '';
    position: absolute;
    inset-block-start: calc(var(--step-dot) / 2);
    inset-inline-start: 50%;
    z-index: -1;
    inline-size: calc(100% + var(--space-5));
    border-block-start: var(--rule-width) solid var(--rule);
  }

  .step__number {
    display: grid;
    place-items: center;
    inline-size: var(--step-dot);
    block-size: var(--step-dot);
    border: var(--border-control) solid var(--fg);
    border-radius: 50%;
    background-color: var(--surface);
    color: var(--fg);
    font-size: var(--text-step-dot);
  }

  .step__title {
    padding-block-start: var(--space-4);
    white-space: nowrap;
  }
}

/* ==========================================================================
   Pricing („Ceník")
   ========================================================================== */

.price-list {
  margin: 0;
  padding: 0;
  list-style: none;
  container-type: inline-size;
}

.price-row {
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
  grid-template-areas:
    'suit main'
    '. price';
  column-gap: var(--space-4);
  padding-block: var(--space-5);
  border-block-start: var(--rule-width) solid var(--rule);
}

.price-row:last-child {
  border-block-end: var(--rule-width) solid var(--rule);
}

.price-row .price-row__suit {
  grid-area: suit;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  margin-block-start: 0.15em;
}

.price-row__main {
  grid-area: main;
}

.price-row__description {
  margin-block-start: var(--space-2);
}

.price-row__includes {
  margin-block-start: var(--space-3);
  padding-inline-start: 1.1em;
  color: var(--fg-muted);
  list-style-type: disc;
}

.price-row__includes li::marker {
  color: var(--fg-muted);
}

.price-row__price {
  grid-area: price;
  margin-block-start: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-price);
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* Wide enough: the price moves into its own column on the right, like a menu. */
@container (min-width: 40rem) {
  .price-row {
    grid-template-columns: 1.5rem minmax(0, 1fr) minmax(10rem, 16rem);
    grid-template-areas: 'suit main price';
    column-gap: var(--space-5);
  }

  .price-row__price {
    margin-block-start: 0;
    text-align: end;
    justify-self: end;
  }
}

.price-note {
  margin-block-start: var(--space-5);
  font-weight: 600;
}

/* ==========================================================================
   FAQ („Časté dotazy")
   ========================================================================== */

.faq {
  max-inline-size: 48rem;
}

.faq__item {
  border-block-start: var(--rule-width) solid var(--rule);
}

.faq__item:last-child {
  border-block-end: var(--rule-width) solid var(--rule);
}

.faq__question {
  position: relative;
  display: flex;
  align-items: center;
  min-block-size: var(--control-height);
  padding-block: var(--space-4);
  padding-inline-end: var(--space-7);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.faq__question::-webkit-details-marker {
  display: none;
}

/* Plus that turns into a minus: two bars, the vertical one lies down when open. */
.faq__question::before,
.faq__question::after {
  content: '';
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: var(--space-2);
  inline-size: 0.875rem;
  block-size: 2px;
  background-color: currentcolor;
  translate: 0 -50%;
}

.faq__question::after {
  rotate: 90deg;
  transition: rotate var(--duration-menu) ease-out;
}

.faq__item[open] > .faq__question::after {
  rotate: 0deg;
}

@media (forced-colors: active) {
  .faq__question::before,
  .faq__question::after {
    background-color: CanvasText;
  }
}

.faq__question:hover > span {
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

.faq__answer {
  padding-block-end: var(--space-5);
}

/* ==========================================================================
   Contact and form („Napište mi")
   ========================================================================== */

.contact {
  display: grid;
  gap: var(--space-8);
}

.contact__noscript {
  margin-block-end: var(--space-5);
  padding: var(--space-4);
  border-inline-start: var(--border-control) solid var(--accent);
  background-color: var(--color-surface-alt);
}

form {
  display: grid;
  gap: var(--space-5);
}

.form-required,
.form-note,
.field-hint {
  color: var(--fg-muted);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.field {
  display: grid;
  gap: var(--space-2);
}

.field label {
  font-size: var(--text-label);
  font-weight: 600;
  line-height: var(--leading-label);
}

.field input,
.field textarea {
  inline-size: 100%;
  min-block-size: var(--control-height);
  padding: var(--space-3) var(--space-4);
  border: var(--rule-width) solid var(--color-field-border);
  border-radius: var(--radius-control);
  background-color: var(--color-surface-alt);
  color: var(--fg);
  line-height: var(--leading-label);
}

.field textarea {
  resize: vertical;
  min-block-size: 10rem;
}

.field input:focus-visible,
.field textarea:focus-visible {
  background-color: var(--color-paper);
}

.field [aria-invalid='true'] {
  border-color: var(--accent);
}

.field-error {
  color: var(--accent);
  font-size: var(--text-small);
  font-weight: 600;
  line-height: var(--leading-small);
}

/* Error slots are always in the DOM; empty ones take no space and add nothing to the name. */
.field-error:empty,
.form-status:empty {
  display: none;
}

.error-summary {
  padding: var(--space-4) var(--space-5);
  border: var(--border-control) solid var(--accent);
  border-radius: var(--radius-control);
}

.error-summary[hidden] {
  display: none;
}

.error-summary__title {
  font-size: var(--text-body);
}

.error-summary__list {
  margin-block-start: var(--space-2);
  padding-inline-start: 1.1em;
}

.error-summary__list a {
  color: var(--accent);
  font-weight: 600;
}

/* Honeypot: out of sight but still in the DOM so bots fill it in. */
.hp {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Empty until Turnstile renders into it (interaction-only mode usually stays invisible). */
.turnstile-slot:empty {
  display: none;
}

.form-submit {
  justify-self: start;
}

.form-submit:disabled {
  cursor: progress;
}

.form-status {
  font-weight: 600;
}

.contact__aside-title {
  font-size: var(--text-h3);
}

/* Address and its Copy button share a row and wrap onto two on the narrowest screens. */
.contact__email {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin-block-start: var(--space-3);
  font-size: var(--text-lead);
  font-weight: 600;
}

/* A small secondary action: lighter than the form's buttons, still a comfortable tap target. */
.copy-button {
  gap: var(--space-1);
  min-block-size: var(--control-height-compact);
  padding-inline: var(--space-2) var(--space-3);
  font-size: var(--text-small);
}

/* Each pair (icon, label) stacks both states in one cell, so the button never changes width
   when it switches to "Zkopírováno". */
.copy-button__swap {
  display: inline-grid;
  justify-items: center;
}

.copy-button__swap > * {
  grid-area: 1 / 1;
}

.copy-button__done,
.copy-button[data-copied] .copy-button__swap > :not(.copy-button__done) {
  visibility: hidden;
}

.copy-button[data-copied] .copy-button__done {
  visibility: visible;
}

.copy-button__icon {
  inline-size: 1rem;
  block-size: 1rem;
  fill: none;
  stroke: currentcolor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Copying needs JavaScript; without it the address stays a plain mailto link. */
@media (scripting: none) {
  .copy-button {
    display: none;
  }
}

.contact__phone {
  margin-block-start: var(--space-2);
  font-size: var(--text-lead);
}

.contact__area {
  margin-block-start: var(--space-5);
  color: var(--fg-muted);
}

@media (min-width: 1024px) {
  .contact {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: start;
  }

  .contact__form {
    grid-column: 1 / span 7;
  }

  .contact__aside {
    grid-column: 8 / span 5;
    padding-block-start: var(--space-5);
    padding-inline-start: var(--space-6);
    border-inline-start: var(--rule-width) solid var(--rule);
  }
}

/* ==========================================================================
   404 and form status pages
   ========================================================================== */

/* The only centred content on the site (brief 4.4). */
.message-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-block: var(--section-space);
  text-align: center;
}

.message-page__title {
  font-size: var(--text-h2);
  line-height: var(--leading-h2);
  max-inline-size: 14em;
}

.message-page__text {
  margin-block-start: var(--space-4);
  max-inline-size: var(--measure-lead);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.message-page__back {
  margin-block-start: var(--space-6);
}

/* ==========================================================================
   Small face-down card (404)
   ========================================================================== */

.small-card {
  --card-w: 7rem;

  inline-size: var(--card-w);
  aspect-ratio: 5 / 7;
  margin-block-end: var(--space-7);
  overflow: hidden;
  border-radius: calc(var(--card-w) * 0.048);
  rotate: -3deg;
}

/* ==========================================================================
   Privacy policy („Zásady ochrany osobních údajů")
   ========================================================================== */

.legal {
  padding-block: var(--section-space);
}

.legal__title {
  font-size: var(--text-h2);
  line-height: var(--leading-h2);
  max-inline-size: 14em;
}

.legal__effective {
  margin-block-start: var(--space-4);
  color: var(--fg-muted);
}

.legal__intro {
  margin-block-start: var(--space-5);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
  max-inline-size: var(--measure-lead);
}

.legal__section {
  margin-block-start: var(--space-7);
  max-inline-size: var(--measure-body);
}

.legal__heading {
  font-size: var(--text-h3);
  font-stretch: 100%;
  font-weight: 650;
  line-height: var(--leading-h3);
}

.legal__section > * + * {
  margin-block-start: var(--space-3);
}

.legal__section ul {
  padding-inline-start: 1.1em;
}

.legal__section li + li {
  margin-block-start: var(--space-2);
}
