/* ===== Self-hosted fonts (mismas que el resto de la suite) =====
       The .woff2 files live under /assets/fonts/ (see CLAUDE.md §"Landing
       typography" and doc/en/technical.md §1). Resolved from
       /css/styles.css that means '../assets/fonts/<file>.woff2' — the
       previous '../fonts/<file>.woff2' resolved to /fonts/<file>.woff2
       (which doesn't exist), silently 404-ing the fonts in production.
       Safari iOS visibly broke on this (long unbroken tokens such as
       'sinonimia.apptonomia.uk' wrap at one character with the wrong
       fallback metrics, clipping the leading characters of every domain);
       Chromium / Firefox fell back to system-ui without the clipping
       artifact, which is why this was easy to miss in cross-browser
       testing without WebKit. Fixing the path is the suite-wide
       directive: "self-hosted, no CDN, no @import" — the woff2 must
       actually load. */
    @font-face {
      font-family: 'Atkinson Hyperlegible';
      font-style: normal;
      font-weight: 400;
      font-display: swap;
      src: url('../assets/fonts/atkinson-hyperlegible-400.woff2') format('woff2');
    }
    @font-face {
      font-family: 'Atkinson Hyperlegible';
      font-style: normal;
      font-weight: 700;
      font-display: swap;
      src: url('../assets/fonts/atkinson-hyperlegible-700.woff2') format('woff2');
    }
    @font-face {
      font-family: 'Nunito';
      font-style: normal;
      font-weight: 400 900;
      font-display: swap;
      src: url('../assets/fonts/nunito-variable.woff2') format('woff2-variations');
    }

    /* ===== Design tokens (alineados con Calculia / Teclatlon / Memofun) ===== */
    :root {
      --color-bg: #FAF7F2;
      --color-surface: #FFFFFF;
      --color-text: #1A1A2E;
      --color-text-soft: #4A4A68;
      --color-border: #D8D2C8;
      --accent: #1B6CA8;
      --accent-soft: #E3EEF6;
      --color-focus: #1B6CA8;
      --color-shadow: rgba(26, 26, 46, 0.12);

      --font: 'Atkinson Hyperlegible', 'Nunito', system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
      --text-base: 18px;
      --text-small: 15px;
      --text-large: 26px;
      --text-title: 38px;

      --space: 16px;
      --space-large: 24px;
      --space-xl: 40px;
      --radius: 16px;
      --button-min: 56px;
      --shadow: 0 2px 8px var(--color-shadow);
    }

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

    html {
      font-size: var(--text-base);
      scroll-behavior: smooth;
    }

    body {
      font-family: var(--font);
      color: var(--color-text);
      background: var(--color-bg);
      /* `100dvh` is the dynamic viewport height — Safari iOS uses the
         actual visible viewport (excluding the address bar), while
         `100vh` includes the bar area and grows when Safari reveals
         the bar on scroll. Stacking `100dvh` after `100vh` means:
         modern engines (Safari 15.4+, Chrome 108+, Firefox 101+)
         use the dynamic value, older engines fall back to 100vh
         which is no worse than before. */
      min-height: 100vh;
      min-height: 100dvh;
      line-height: 1.5;
      -webkit-font-smoothing: antialiased;
      display: flex;
      flex-direction: column;
    }

    a { color: var(--accent); text-decoration: none; }
    a:hover { text-decoration: underline; }

    h1 { font-size: var(--text-title); line-height: 1.15; letter-spacing: -0.02em; }
    h2 { font-size: var(--text-large); line-height: 1.25; }
    h3 { font-size: 22px; line-height: 1.3; }
    p  { max-width: 38em; color: var(--color-text-soft); }

    :focus-visible {
      outline: 3px solid var(--color-focus);
      outline-offset: 3px;
      border-radius: 4px;
    }

    .sr-only {
      position: absolute;
      width: 1px; height: 1px;
      padding: 0; margin: -1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
      border: 0;
    }

    .skip-link {
      position: absolute;
      left: -9999px;
      top: 0;
      background: var(--accent);
      color: #fff;
      padding: 12px 18px;
      border-radius: 0 0 var(--radius) var(--radius);
      z-index: 100;
    }
    .skip-link:focus { left: 16px; top: 16px; }

    .container {
      width: 100%;
      max-width: 1400px;
      margin: 0 auto;
      padding: 0 48px;
      /* Safari iOS + flexbox interaction bug: with `min-height: 100vh`
         here, Safari (WebKit) mis-interprets the container's intrinsic
         height and clamps the descendant grid to the viewport height
         instead of letting it size from its content. The user-visible
         effect is that the suite grid collapses below the fold on
         initial load — only the header (which has flex-shrink:0)
         shows, and the seven project cards stay invisible until the
         page is manually scrolled. The body already enforces
         min-height:100vh via `display:flex; flex-direction:column;`,
         so duplicating it on the inner container just feeds the bug.
         Keeping the container as a plain block lets Safari size the
         grid from its content, and the body's flex layout still
         pushes the footer down when the page is shorter than the
         viewport. */
    }

    /* ===== Header ===== */
    .app-header {
      padding: var(--space) 0 var(--space-large);
      flex-shrink: 0;
    }
    .top-bar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--space);
    }
    .brand {
      display: inline-flex;
      align-items: center;
      gap: 12px;
      font-weight: 700;
      color: var(--color-text);
    }
    .brand:hover { text-decoration: none; }
    .brand-mark {
      width: 40px; height: 40px;
      border-radius: 12px;
      background: var(--color-text);
      color: #fff;
      display: grid; place-items: center;
      font-weight: 800; font-size: 22px;
    }
    .brand-name { font-size: 22px; letter-spacing: -0.02em; }

    .lang-switch {
      display: inline-flex;
      gap: 6px;
      background: var(--color-surface);
      border: 1px solid var(--color-border);
      border-radius: 999px;
      padding: 4px;
    }
    .btn-lang {
      border: 0;
      background: transparent;
      padding: 8px 14px;
      border-radius: 999px;
      font: inherit;
      font-weight: 600;
      color: var(--color-text-soft);
      cursor: pointer;
      min-height: 40px;
    }
    .btn-lang[aria-pressed="true"] {
      background: var(--accent);
      color: #fff;
    }

    .app-hero {
      text-align: center;
      padding-top: 32px;
      flex-shrink: 0;
    }
    .app-hero h1 {
      max-width: 18ch;
      margin: 0 auto var(--space);
      font-size: 56px;
    }
    .app-hero .hero-tagline {
      margin: 0 auto;
      max-width: 38ch;
      font-size: 24px;
      line-height: 1.45;
      color: var(--color-text-soft);
      letter-spacing: -0.01em;
    }

    /* ===== Suite grid ===== */
    main {
      /* Plain block, not flex: WebKit (Safari/iOS) refuses to grow a
         flex column item to fit a grid descendant when its parent
         container has min-height:100vh, so the grid collapses to 0
         height and the cards never paint (visible as "only the
         title shows, not the cards"). Keeping main in block flow
         and letting the body own the flex layout lets the grid size
         from its actual content. */
      padding: 24px 0;
    }

    .suite {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
      gap: 24px;
      align-content: start;
    }

    .suite-card {
      display: flex;
      flex-direction: column;
      gap: 12px;
      padding: var(--space-large);
      background: var(--color-surface);
      border: 1px solid var(--color-border);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      color: var(--color-text);
      text-decoration: none;
      min-height: 180px;
      /* iOS Safari/WebKit otherwise refuses to shrink a grid item below its
         intrinsic content width: an unbroken token such as
         'sinonimia.apptonomia.uk' inside .suite-domain widens the column
         past the viewport and overflows the layout to the left (matches
         the sinonimia .buscador-fila #buscar min-width: 0 fix). Forcing
         min-width: 0 lets the grid track actually govern the card's width
         on every engine, no UA sniffing required. */
      min-width: 0;
      transition: transform 0.15s ease, box-shadow 0.15s ease;
    }
    .suite-card:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 16px var(--color-shadow);
      text-decoration: none;
    }

    /* ===== "Próximamente" cards =====.
       Calculia / Routime / Okeymoney / Ludia are not yet shipped, so
       they ship as <div role="link" aria-disabled="true"> with no
       href. The visual treatment below makes it obvious that the card
       is not a navigation target:
         • cursor: not-allowed, no hover lift;
         • softened colour and opacity so it sits behind the live
           siblings in the visual hierarchy;
         • a "Próximamente" badge replaces the suite-domain slot, so
           the card does not advertise a URL the visitor cannot follow.
       The CSS keeps the card the same shape as the live siblings so
       the grid rhythm stays consistent. */
    .suite-card--soon {
      cursor: not-allowed;
      background: var(--color-surface);
      color: var(--color-text-soft);
      /* Slightly desaturated so it visually recedes vs the live cards.
         opacity also keeps the pictogram from competing with the ones
         that are actually clickable. */
      opacity: 0.72;
      filter: saturate(0.55);
    }
    .suite-card--soon:hover {
      transform: none;
      box-shadow: var(--shadow);
    }
    .suite-card--soon:focus,
    .suite-card--soon:focus-visible {
      outline: none;
    }
    .suite-card--soon .suite-picto {
      opacity: 0.85;
    }
    .suite-card--soon h3 {
      color: var(--color-text-soft);
    }
    .suite-card--soon p {
      /* Keep the description readable but not as loud as on a live card. */
      color: var(--color-text-soft);
      opacity: 0.85;
    }
    .suite-soon-badge {
      margin-top: auto;
      align-self: flex-start;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: var(--color-text);
      background: var(--accent-soft);
      padding: 6px 12px;
      border-radius: 999px;
    }
    .suite-card-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    .suite-picto {
      width: 44px; height: 44px;
      border-radius: 12px;
      display: grid; place-items: center;
      font-size: 22px;
      background: var(--accent-soft);
    }
    /* When the pictogram is an <img> (sibling's own SVG icon, currently
       only Memofun ships one) instead of an emoji glyph, scale the
       SVG down to leave breathing room inside the 44×44 accent-soft
       chip and let the SVG's own rounded corners do the rest. The
       `<img>` keeps the SVG's intrinsic aspect-ratio so it stays
       centered both horizontally and vertically via the grid above. */
    .suite-picto--svg img {
      width: 36px;
      height: 36px;
      display: block;
    }
    .suite-tag {
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: var(--color-text-soft);
    }
    .suite-card h3 {
      font-size: 22px;
      letter-spacing: -0.01em;
    }
    .suite-card p {
      font-size: 15px;
      line-height: 1.5;
      color: var(--color-text-soft);
    }
    .suite-domain {
      margin-top: auto;
      font-size: 13px;
      font-weight: 600;
      color: var(--color-text);
      opacity: 0.7;
      font-variant-numeric: tabular-nums;
      /* The domain string is one unbroken token (no spaces, no hyphens
         in some cases). Without this, Safari iOS lets it overflow the
         .suite-card column even after the min-width: 0 fix above; other
         engines break it on the dot. overflow-wrap: anywhere is the
         cross-browser equivalent that wraps at any character if the
         token is wider than the column. */
      overflow-wrap: anywhere;
      word-break: break-word;
    }

    /* ===== Footer ===== */
    .app-footer {
      padding: var(--space-large) 0 var(--space);
      color: var(--color-text-soft);
      font-size: 14px;
      flex-shrink: 0;
    }
    .app-footer .container {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: var(--space);
      flex-wrap: wrap;
    }

    @media (max-width: 640px) {
      .container { padding: 0 16px; }
      .app-header { padding-bottom: 8px; }
      .app-hero { padding-top: 16px; }
      .app-hero h1 { font-size: clamp(34px, 10vw, 46px); }
      .app-hero .hero-tagline { font-size: 19px; }
      main { padding: 16px 0; }
      .suite { grid-template-columns: 1fr; gap: 14px; align-content: start; }
      .suite-card { min-height: 150px; padding: 18px; }
      .app-footer { padding-top: 8px; }
    }
    
    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
      }
    }


/* Compact suite header: branding and controls share one row. */
header.suite-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px 16px;
  padding-block: 8px;
  margin-bottom: 0;
  text-align: left;
}
.suite-header .suite-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 0;
}
.suite-header .suite-brand > img,
.suite-header .hero-mark { width: 44px; height: 44px; flex: 0 0 44px; margin: 0; }
.suite-header .hero-mark img { width: 100%; height: 100%; }
.suite-header .suite-brand-copy { min-width: 0; }
.suite-header .suite-brand-copy h1,
.suite-header .suite-brand-copy .logo,
.suite-header .brand {
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  color: var(--accent);
  font-size: 28px;
  line-height: 1.1;
  text-align: left;
}
.suite-header .suite-attribution {
  position: static;
  margin: 2px 0 0;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: normal;
  color: inherit;
}
.suite-attribution a { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 0.15em; }
.suite-attribution a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 2px; }
.suite-header .suite-controls,
.suite-header .suite-controls [role="group"] { display: flex; align-items: center; justify-content: flex-end; flex-wrap: nowrap; gap: 6px; margin: 0; }
.suite-header .suite-controls button {
  min-width: 44px;
  min-height: 44px;
  padding: 8px 10px;
  font-size: 14px;
  line-height: 1.2;
  border-width: 2px;
  white-space: nowrap;
}
.suite-header .locale-short { display: none; }
.suite-header .suite-details {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}
.suite-header .suite-details .fila { justify-content: flex-start; min-width: 0; flex: 1; margin: 0; gap: 8px; }
.suite-header .saludo,
.suite-header .tagline { font-weight: 400; color: var(--color-text-soft); margin: 0; max-width: none; font-size: 18px; line-height: 1.35; text-align: left; }
.suite-header .stars { min-height: 0; background: var(--accent-2-soft, #F7EFDD); border-radius: 999px; flex: 0 0 auto; margin: 0; padding: 2px 8px; font-size: 18px; line-height: 1.3; white-space: nowrap; }
@media (max-width: 650px) {
  header.suite-header { gap: 6px 8px; padding-block: 8px; margin-bottom: 0; }
  .suite-header .suite-brand { gap: 8px; }
  .suite-header .suite-brand > img,
  .suite-header .hero-mark { width: 32px; height: 32px; flex-basis: 32px; }
  .suite-header .suite-brand-copy h1,
  .suite-header .suite-brand-copy .logo,
  .suite-header .brand { font-size: 22px; }
  .suite-header .locale-full { display: none; }
  .suite-header .locale-short { display: inline; }
  .suite-header .suite-controls button { padding-inline: 6px; }
  .suite-header .saludo,
  .suite-header .tagline { font-size: 16px; }
}


.suite-header .lang-switch { padding: 0; background: transparent; border: 0; border-radius: 0; }
.suite-header .btn-lang { border: 2px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); font-weight: 700; }
.suite-header .btn-lang[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--color-text); }
.suite-header .brand-mark { display: grid; place-items: center; }
header.suite-header.container { padding-inline: 48px; }
@media (max-width: 650px) {
  header.suite-header.container { padding-inline: 12px; }
}
