/* Home. One centred column — wordmark, search, tiles — over the particle
   field, with nothing boxed in a panel. The rail already lists every
   destination, so the home page's job is just to get you moving. */

/* The home view is a single locked screen: it fills the window exactly and
   never scrolls — vertically or horizontally — whatever the user does.
   page-main.css is loaded by main.html only, so pinning the document here
   is safe. body itself is fixed (not just overflow:hidden) because that is
   the only thing iOS Safari actually honours. */
    html {
      height: 100%;
      overflow: hidden;
    }
    body {
      position: fixed;
      inset: 0;
      overflow: hidden;
      overscroll-behavior: none;
    }

/* The stage fills the fixed body and clips anything that doesn't fit rather
   than growing a scrollbar. */
    .ol-stage.home {
      display: flex;
      height: 100%;
      min-height: 0;
      overflow: hidden;
      padding: 40px clamp(16px, 3vw, 32px);
    }
    /* The home column is the one thing on the site that should sit on the
       window's centre line, not centred in whatever space is left beside the
       rail — which is what the stage's margin-left would give it. So it drops
       the margin and reserves the rail's width on *both* sides instead: dead
       centre, and still no way to slide under the rail.
       "body" is needed to outweigh ui.css's "body.rail-open .ol-stage". */
    @media (min-width: 821px) {
      body .ol-stage.home { margin-left: 0; padding-inline: var(--rail); }
      body.rail-open .ol-stage.home { padding-inline: var(--rail-open); }
    }
    /* "margin: auto" rather than align-items/place-items: centring this way
       degrades to top-aligned when the column is taller than the viewport,
       instead of overflowing off the top edge where it can't be scrolled to. */
    .home-inner {
      margin: auto;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 22px;
      width: min(680px, 100%);
    }

    .hero { position: relative; display: grid; justify-items: center; gap: 10px; }
    /* Soft bloom behind the wordmark, in the logo's own cyan. Sits under the
       text but over the particles. */
    .hero::before {
      content: "";
      position: absolute;
      left: 50%;
      top: 46%;
      width: 380px;
      height: 180px;
      transform: translate(-50%, -50%);
      background: radial-gradient(50% 50% at 50% 50%,
        hsl(var(--bg-h) var(--bg-s) 62% / 0.16),
        hsl(var(--bg-h) var(--bg-s) 62% / 0.06) 45%, transparent 72%);
      filter: blur(30px);
      pointer-events: none;
    }
    .hero-logo {
      position: relative;
      width: min(380px, 84%);
      height: auto;
      display: block;
    }
    /* Temporary text wordmark in place of the logo image. */
    .hero-wordmark {
      width: auto;
      font-size: clamp(52px, 12vw, 108px);
      font-weight: 700;
      letter-spacing: -0.045em;
      line-height: 1;
      text-align: center;
      /* White fading into the live theme accent — --accent-color is the same
         custom property theme.js drives everything else from, so this tracks
         whatever colour the user picks with no extra wiring. Defaults to a
         solid white wordmark, since the default accent is white too. */
      background: linear-gradient(115deg, #ffffff 0%, #ffffff 45%, var(--accent-color) 100%);
      -webkit-background-clip: text;
              background-clip: text;
      color: transparent;
      -webkit-text-fill-color: transparent;
    }
    .hero-tag {
      position: relative;
      color: var(--text-dim);
      font-size: 14px;
      text-align: center;
      min-height: 1.4em;
      transition: opacity 0.35s ease; /* fades between rotating taglines */
    }

    .search-bar {
      position: relative;
      display: flex;
      align-items: center;
      gap: 12px;
      width: 100%;
      padding: 8px 10px 8px 18px;
      /* No fill — just a white outline over the page's own black background, so
         the bar reads as an outlined box that blends into the backdrop. */
      background: transparent;
      border: 1px solid var(--line);
      border-radius: 0;
      transition: border-color 0.16s ease, box-shadow 0.16s ease;
    }
    .search-bar:hover { border-color: var(--line-strong); }
    .search-bar:focus-within {
      border-color: var(--accent-line);
      box-shadow: 0 0 0 4px var(--accent-soft);
    }
    /* A white comet that continuously traces the bar's own border. The ring
       is a conic-gradient sitting a hair outside the real border, punched
       down to just its outline via the mask-composite "ring" trick (fill the
       box twice — once padded out, once inset to content-box — and XOR them
       away so only the band between the two survives). --beam-angle is
       registered below so the browser tweens it smoothly instead of jumping
       between keyframes. */
    @property --beam-angle {
      syntax: "<angle>";
      inherits: false;
      initial-value: 0deg;
    }
    .search-bar::after {
      content: "";
      position: absolute;
      inset: -1px;
      padding: 1px;
      border-radius: inherit;
      pointer-events: none;
      background: conic-gradient(
        from var(--beam-angle),
        transparent 0%,
        transparent 72%,
        rgba(255, 255, 255, 0.5) 84%,
        #ffffff 90%,
        rgba(255, 255, 255, 0.5) 96%,
        transparent 100%
      );
      -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
      animation: search-beam-spin 3.6s linear infinite;
    }
    @keyframes search-beam-spin {
      to { --beam-angle: 360deg; }
    }
    .search-bar svg { width: 20px; height: 20px; color: var(--text-faint); flex-shrink: 0; transition: color 0.16s ease; }
    .search-bar:focus-within svg { color: var(--accent-color); }
    .search-input {
      flex: 1;
      min-width: 0;
      min-height: 46px;
      background: none;
      border: none;
      color: var(--text);
      font: inherit;
      font-size: 15.5px;
      letter-spacing: -0.01em;
      outline: none;
    }
    .search-input::placeholder { color: var(--text-faint); }
    .search-engine {
      min-height: 34px;
      padding: 0 10px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      border-radius: 0;
      background: transparent;
      color: var(--text-dim);
      font: inherit;
      font-size: 12.5px;
      cursor: pointer;
      outline: none;
      transition: border-color 0.14s ease, color 0.14s ease;
    }
    .search-engine:hover { color: var(--text); border-color: var(--accent-line); }
    .search-engine option { background: #0b0d14; color: var(--text); }
    .search-kbd {
      flex-shrink: 0;
      margin-right: 6px;
      padding: 5px 9px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      border-radius: 0;
      background: transparent;
      color: var(--text-faint);
      font-size: 11px;
      font-weight: 500;
      letter-spacing: 0.02em;
    }

    /* Tiles are a centred row that wraps, not a grid — a short row should sit
       in the middle under the search bar, not stretch to fill columns. */
    .app-row {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 10px;
    }
    .app-tile {
      position: relative;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 9px;
      width: 96px;
      min-height: 96px;
      padding: 14px 8px;
      border: 1px solid var(--line);
      border-radius: 0;
      background: var(--surface);
      backdrop-filter: blur(18px);
      -webkit-backdrop-filter: blur(18px);
      text-decoration: none;
      text-align: center;
      font: inherit;
      cursor: pointer;
      transition: background 0.14s ease, border-color 0.14s ease, transform 0.14s ease;
    }
    .app-tile:hover {
      background: var(--surface-hover);
      border-color: var(--accent-line);
      transform: translateY(-2px);
    }
    .app-tile img, .app-tile .letter, .app-tile .add-icon {
      width: 34px;
      height: 34px;
      border-radius: 0;
      object-fit: contain;
      flex-shrink: 0;
    }
    /* Kept at .app-tile-level specificity: the ".app-tile span" label rule
       below is (0,1,1) and would otherwise win the font-size here. */
    .app-tile .letter, .app-tile .add-icon {
      display: grid;
      place-items: center;
      font-size: 17px;
      font-weight: 600;
      color: var(--acc-ink);
      background: var(--accent);
    }
    .app-tile .add-icon {
      background: none;
      border: 1.5px dashed var(--line-strong);
      color: var(--text-faint);
      font-size: 20px;
      font-weight: 400;
    }
    .app-tile span { font-size: 12px; color: var(--text-dim); line-height: 1.25; }
    .app-tile:hover span { color: var(--text); }

    .tile-wrap { position: relative; display: flex; }
    .tile-wrap .app-tile { flex: 1; }
    .tile-delete {
      position: absolute;
      top: 7px;
      right: 7px;
      width: 22px;
      height: 22px;
      display: none;
      place-items: center;
      border: none;
      border-radius: 50%;
      background: var(--danger);
      color: #fff;
      font-size: 14px;
      line-height: 1;
      cursor: pointer;
    }
    .tile-wrap:hover .tile-delete, .tile-delete:focus-visible { display: grid; }

    .modal-overlay {
      position: fixed;
      inset: 0;
      z-index: 200;
      display: none;
      place-items: center;
      padding: 20px;
      background: rgba(6, 6, 6, 0.78);
      backdrop-filter: blur(6px);
    }
    .modal-overlay.open { display: grid; }
    .modal { width: min(400px, 100%); padding: 22px; }
    .modal h2 { font-size: 18px; margin-bottom: 16px; }
    .modal .ol-input { margin-bottom: 10px; }
    .modal-actions { display: flex; gap: 8px; margin-top: 14px; }
    .modal-actions .ol-btn { flex: 1; }

    /* Narrow: the rail is a bottom bar, so the column stops fighting it for
       vertical space and the engine picker gives up its seat in the pill. */
    @media (max-width: 820px) {
      /* Needs the descendant selector to outweigh ui.css's
         "body.rail-open .ol-stage" padding-bottom, which otherwise applies
         only when the rail happens to be open. */
      body .ol-stage.home {
        min-height: auto;
        padding: 32px clamp(16px, 3vw, 32px) 100px;
      }
      .hero::before { width: 300px; height: 170px; }
      .search-kbd { display: none; }
    }
    @media (max-width: 480px) {
      .search-engine { display: none; }
      .app-tile { width: 84px; }
    }

