/* Responsive */
@media (max-width: 768px) {
  .terminal-window {
    padding: 0 16px;
  }

  .neofetch {
    flex-direction: column;
    gap: 16px;
  }

  .neofetch-logo {
    font-size: 8px;
    text-align: center;
  }

  .neofetch-row {
    flex-direction: column;
    gap: 2px;
  }

  .neofetch-row .label {
    min-width: auto;
  }

  .history-entry {
    padding: 14px 14px;
    margin-bottom: 20px;
  }

  /* No .skill-name min-width. skills.css gives it `flex: 1; min-width: 0` so
     it takes the slack and wraps inside its own column; a floor here only
     fights that. */
  .skill-name {
    font-size: 0.85rem;
  }

  .skill-icons .icon {
    width: 16px;
    height: 16px;
  }

  .cert-entry {
    flex-direction: column;
    gap: 8px;
  }

  /* Stacks like every other two-part row in this block. Left as a flex row it
     kept ~70px for "FOSDEM" and wedged "Brussels, Belgium · 2020, 2023, 2024,
     2025, 2026" into the remainder over three ragged lines. */
  .conf-entry {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .ctf-row {
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
  }

  .ctf-platform {
    min-width: auto;
  }

  .review-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .contact-row {
    flex-direction: column;
    gap: 2px;
  }

  .contact-label {
    min-width: auto;
  }

  .section-title {
    font-size: 1.05rem;
  }

  .tab-bar a {
    padding: 0 12px;
    font-size: 0.72rem;
  }

  /* Tracks the smaller type above: arrow plus label measures 88px here.
     Kept in step with .tab-home's real width because scroll-padding-left
     reads the same variable. */
  .tab-bar {
    --tab-home-w: 120px;
  }

  .tab-actions button {
    padding: 0 8px;
    font-size: 0.7rem;
  }

  #hero {
    /* Hub raises its gap to 36px below its 760px step; this block's 768px
       step is the nearest cv breakpoint, so the two agree except in the
       761-768px band. */
    padding-top: 36px;
  }

  .section {
    margin-bottom: 48px;
  }

  /* Single column all the way up to 900px, matching .mission-grid,
     .project-group-inner and .hobbies-split. It used to return to two columns
     at 769px, where each skill name got ~160px and long ones wrapped to three
     lines. */
  .skill-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  .skill-category {
    padding: 14px 14px;
  }

  .edu-entry {
    padding: 14px 14px;
  }

  .project-entry {
    padding: 10px 12px;
  }

  .about-layout {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

@media (max-width: 480px) {
  /* The root font-size is deliberately NOT reduced here.
     This block used to set 14px, which scaled every rem-based size on the page
     down by 12.5% on exactly the screens with the least room and the worst
     viewing conditions. Because almost every rule on this site sizes below
     1rem, the knock-on was that most body copy landed between 9px and 12px:
     .tab-bar a at 9.5, .project-tag at 9.1, .project-desc at 11.5,
     .skill-name at 11.9. Small screens need type at least as large as a
     desktop's, not smaller. Anything that genuinely needs to shrink on a phone
     is shrunk explicitly below. */

  .terminal-window {
    padding: 0 10px;
  }

  /* The fixed "Get in touch" pill floats over the bottom-right corner for the
     whole page and body had padding-bottom: 0, so the last rows of any section
     -- and the footer's copyright lines -- sat permanently underneath it with
     no way to scroll them clear. */
  body {
    padding-bottom: 80px;
  }

  /* No .ascii-art rules here: every viewport this block matches also matches
     the (max-width: 560px) block below, which hides the banner entirely. */

  .neofetch-logo {
    display: none;
  }

  /* No #hero override here: the hub has no step below 760px, so the 36px set
     in the 768px query carries down to the smallest screens. */

  #hero-typing {
    min-height: 220px;
  }

  .prompt {
    font-size: 0.8rem;
    word-break: break-word;
  }

  .section-title {
    font-size: 0.95rem;
  }

  .tab-bar a {
    padding: 0 8px;
    font-size: 0.68rem;
    gap: 4px;
  }

  .tab-bar a .icon {
    width: 11px;
    height: 11px;
  }

  /* Below 480px the parent link drops its label and keeps only the arrow.
     This is not cosmetic — it is the difference between the bar working and
     not working. Both ends of the bar are pinned, so they cost real width:
     the three action buttons take 132px (44px each, below), and a labelled
     "luyckx.dev" took ~96px more. On a 320px screen that left ~92px of
     unobscured middle, and "Testimonials" needs ~109px. No amount of
     scrolling or scroll-padding creates space that is not there, so the
     longest tabs simply could never be read in full. At 44px the middle is
     ~144px and every tab fits.

     44px, not the ~27px the icon needs, for the same reason the buttons
     below are 44px: it is the minimum comfortable tap target, and this is
     the control someone taps to leave. The label survives as the anchor's
     aria-label, so the accessible name does not change with the viewport. */
  .tab-bar {
    --tab-home-w: 44px;
  }

  .tab-bar .tab-home span {
    display: none;
  }

  /* Skill rows stay on ONE line on a phone.
     They used to wrap: .skill-name had min-width:100%, which pushed the five
     icons and the score onto a second, left-aligned line. That did two bad
     things at once -- it doubled the height of all 74 rows (~4,200px of
     scrolling in one section) and it destroyed the right-pinned rating column,
     which is the only thing that lets you compare scores by running your eye
     down a card.

     The space is there: at 320px the card's inner width is 270px and the
     rating block costs 108px, leaving ~162px for the name. `flex: 1;
     min-width: 0` from skills.css wraps a long name over two lines inside its
     own column, which is the correct behaviour. */
  .skill-row {
    gap: 10px;
  }

  .skill-name {
    font-size: 0.82rem;
    line-height: 1.35;
  }

  .skill-icons {
    gap: 3px;
  }

  .skill-icons .icon {
    width: 15px;
    height: 15px;
  }

  .skill-value {
    font-size: 0.75rem;
  }

  .skill-subhead {
    font-size: 0.68rem;
    margin: 14px 0 6px;
  }

  .skill-category-title {
    font-size: 0.85rem;
  }

  .edu-entry {
    padding: 10px 10px;
  }

  .history-content .desc {
    font-size: 0.82rem;
  }

  .ctf-badge {
    font-size: 0.7rem;
  }

  .cert-full {
    font-size: 0.82rem;
  }

  .project-entry {
    padding: 8px 10px;
  }

  .project-desc {
    font-size: 0.82rem;
  }

  .project-tag {
    font-size: 0.65rem;
  }

  /* Every standalone control below is padded to the 44px minimum touch target.
     Inline links inside sentences are deliberately left alone -- padding those
     would overlap adjacent lines, and WCAG exempts links in a block of text. */
  .fixed-cta {
    bottom: 16px;
    right: 16px;
    padding: 13px 18px;
    font-size: 0.78rem;
  }

  .hero-cta {
    padding: 12px 20px;
    font-size: 0.82rem;
  }

  .scroll-cue {
    width: 44px;
    height: 44px;
  }

  /* Standalone rows in the contact list, not prose links. */
  .contact-value a {
    display: inline-block;
    padding: 10px 0;
  }

  .site-footer {
    padding: 16px 10px 20px;
    font-size: 0.7rem;
  }

  /* 44px wide, not 23-30px. These are the theme, language and palette buttons;
     they were the narrowest targets on the page and sit shoulder to shoulder
     separated only by a 1px border. */
  .tab-actions button {
    padding: 0 10px;
    min-width: 44px;
    justify-content: center;
    font-size: 0.7rem;
  }

  .hero-cta-secondary {
    padding: 12px 20px;
    font-size: 0.82rem;
  }

  .cert-issuer { font-size: 0.85rem; }
  .review-badge { font-size: 0.82rem; }
  .review-role { font-size: 0.88rem; }

  .card:hover {
    transform: none;
    box-shadow: none;
  }
}

/* Small screens: a readable name instead of an unreadable banner ────
   The figlet banner is 95 columns wide. Fitting that into ~288px of
   content forces a 3.8px glyph cell, which is not small text -- it is an
   illegible smear that still costs its full height. Below 560px it is hidden
   and the page's real <h1>, which until now was screen-reader-only, is shown
   in its place. Nothing is lost: the banner is aria-hidden decoration and the
   h1 carries the same words.

   The un-hiding has to undo every part of the .sr-only clip, not just the
   position, or the heading stays a 1px box. */
@media (max-width: 560px) {
  .ascii-art { display: none; }

  .banner-title {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    margin: 0 0 16px;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
    font-size: clamp(1.15rem, 5.5vw, 1.5rem);
    font-weight: 700;
    line-height: 1.25;
    color: var(--pink);
  }
}
