  :root { color-scheme: dark; }
  * { margin:0; padding:0; box-sizing:border-box; }
  html,body { height:100%; overflow:hidden; background:#0a0a0f; }
  body {
    font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans", sans-serif;
    -webkit-text-size-adjust:100%;
  }
  /* 最初の一枚が描けるまで背景は伏せておく。
     WebGPU はシェーダーの用意に時間がかかるので、黒い画面が突然
     風景に切り替わる。伏せてから滲ませると、夜が明けるように見える。
     この間、待っている感じを埋めるのがタイトルの描画アニメーション。 */
  canvas {
    display:block; width:100%; height:100%; touch-action:none;
    opacity:0; transition:opacity 1.6s cubic-bezier(.4,0,.2,1);
  }
  canvas.ready { opacity:1; }
  @media (prefers-reduced-motion:reduce) {
    canvas { transition:opacity .3s linear; }
  }

  #ui {
    position:fixed; left:12px; bottom:calc(12px + env(safe-area-inset-bottom));
    width:min(280px, calc(100vw - 24px));
    background:rgba(12,12,18,.62);
    -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
    border:1px solid rgba(255,255,255,.10); border-radius:14px;
    padding:12px 14px; color:#e9e6e0; font-size:12px; letter-spacing:.02em;
    transition:opacity .25s;
  }
  #ui.hide { opacity:0; pointer-events:none; }
  #toggle {
    position:fixed; right:12px; bottom:calc(12px + env(safe-area-inset-bottom));
    width:42px; height:42px; border-radius:50%; z-index:10;
    background:rgba(12,12,18,.62); border:1px solid rgba(255,255,255,.10);
    -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
    color:#e9e6e0; font-size:16px; line-height:42px; text-align:center; cursor:pointer;
    transition:opacity .55s cubic-bezier(.4,0,.2,1);
    -webkit-tap-highlight-color:transparent; user-select:none; -webkit-user-select:none;
  }
  #toggle.hide { opacity:0; pointer-events:none; }
  #ui { max-height:calc(100vh - 96px); overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; }
  .pills { display:flex; gap:8px; margin:12px 0 2px; }
  .pills + .pills { margin-top:8px; }
  .pill {
    flex:1; text-align:center; padding:8px 0; border-radius:9px;
    border:1px solid rgba(255,255,255,.13); background:rgba(255,255,255,.05);
    font-size:11px; cursor:pointer; user-select:none; -webkit-user-select:none;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
    transition:background .18s, color .18s, border-color .18s;
    text-decoration:none;
  }
  .pill.on { background:rgba(240,217,184,.88); color:#1a1206; border-color:transparent; }
  a.pill { display:block; color:#e9e6e0; }
  a.pill:hover, a.pill:focus-visible {
    background:rgba(255,255,255,.12); border-color:rgba(255,255,255,.26);
  }
  #ui .cap { font-size:11px; font-weight:600; letter-spacing:.14em; opacity:.55; margin-bottom:10px; }
  .row { display:flex; align-items:center; gap:9px; margin:9px 0; min-width:0; }
  .row label { flex:0 0 72px; opacity:.72; font-size:11px; white-space:nowrap; }
  .row output { flex:0 0 36px; text-align:right; opacity:.45; font-variant-numeric:tabular-nums; font-size:10px; }
  input[type=range] {
    flex:1 1 0; min-width:0; -webkit-appearance:none; appearance:none;
    background:rgba(255,255,255,.22); border-radius:2px; outline:none;
    /* 指で掴める高さを確保する。線は 2px のまま見せたいので、
       背景は内容領域にだけ描き、広げたぶんは margin で戻して行の高さを変えない。
       box-sizing が border-box なので、24px から上下の padding を引いた 2px が線になる */
    height:24px; padding:11px 0; margin:-11px 0; background-clip:content-box;
  }
  input[type=range]::-webkit-slider-thumb {
    -webkit-appearance:none; width:15px; height:15px; border-radius:50%;
    background:#f0d9b8; box-shadow:0 0 0 1px rgba(0,0,0,.35);
  }
  input[type=range]::-moz-range-thumb {
    width:15px; height:15px; border:none; border-radius:50%; background:#f0d9b8;
  }
  #hint { margin-top:10px; font-size:10px; opacity:.35; line-height:1.5; }
  /* --- タイトル --- */
  #splash {
    position:fixed; inset:0; z-index:20;
    display:grid; grid-template-rows:1fr auto; justify-items:center; align-items:center;
    /* 昼に開くと空も砂も明るい。中心まで完全に透かすと文字が沈むので、
       景色を見せたまま、読める下限だけ確保する */
    background:
      radial-gradient(120% 80% at 50% 60%, rgba(8,10,16,.26) 0%, rgba(8,10,16,.62) 70%, rgba(8,10,16,.88) 100%);
    transition:opacity .9s cubic-bezier(.4,0,.2,1), visibility .9s;
    cursor:pointer; -webkit-tap-highlight-color:transparent;
  }
  #splash.gone { opacity:0; visibility:hidden; }
  .sp-in { text-align:center; padding:24px; }
  /* タイトルは image/beach.svg の字。文字としての意味は aria-label で持たせる */
  #splash h1 { line-height:0; }
  #splash h1 svg {
    display:block; width:clamp(210px, 46vw, 380px); height:auto;
    color:#EDE6DA; filter:drop-shadow(0 2px 40px rgba(0,0,0,.55));
  }
  /* 明るい時間帯でも字が浮くように、うしろへ薄い影を落とす */
  .sp-in > *, .sp-foot { text-shadow:0 1px 16px rgba(8,10,16,.85); }
  /* --- タイトル：白い水が下から満ちる ---
     マスクの中に「波打つ水面」を置き、それを下から上へ動かす。
     水面は横にも流し続けるので、上がりながら揺れて見える。
     横の流れは波長ちょうどで折り返すため、継ぎ目が出ない。 */
  /* 水は静かに上がりはじめ、終盤で一気に満ちる。
     字は y=0〜89.8 にあるので、その少し下から少し上までを動かす
     （見えないところを長く動かすと、そのぶん待ち時間になる） */
  .bch-rise { animation:bch-rise 2400ms cubic-bezier(.35,.05,.95,1) forwards; }
  .bch-wave { animation:bch-wave 1500ms linear infinite; }
  @keyframes bch-rise {
    from { transform:translateY(92px); }    /* 字のすぐ下。空白の時間を作らない */
    to   { transform:translateY(-6px); }    /* 字のすぐ上。満ちきる */
  }
  @keyframes bch-wave {
    from { transform:translateX(0); }
    to   { transform:translateX(-47.9px); } /* 波長ぶんずらすと、見た目が元に戻る */
  }
  @media (prefers-reduced-motion:reduce) {
    .bch-rise { animation:none; transform:translateY(-6px); }
    .bch-wave { animation:none; }
  }

  .sp-sub {
    margin-top:22px; font-size:12px; letter-spacing:.34em; text-indent:.34em;
    color:rgba(233,226,214,.62);
  }
  .sp-go {
    margin-top:52px; display:inline-flex; align-items:center; gap:9px;
    padding:13px 26px 13px 22px; border-radius:999px;
    border:1px solid rgba(233,226,214,.30); background:rgba(10,13,20,.30);
    -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
    color:#EDE6DA; font-size:12px;
    animation:breathe 3.4s ease-in-out infinite;
  }
  /* 字間はラベルだけに掛ける。ボタン全体に掛けるとアイコンとの間が開きすぎる */
  .sp-go span { letter-spacing:.20em; text-indent:.20em; }
  .sp-go svg { width:15px; height:15px; flex:none; opacity:.88; }
  .sp-note {
    margin-top:26px; font-size:10px; letter-spacing:.18em;
    color:rgba(233,226,214,.50);
  }
  @keyframes breathe { 0%,100%{opacity:.55} 50%{opacity:1} }
  @media (prefers-reduced-motion:reduce) { .sp-go { animation:none; opacity:.9; } }

  /* --- タイトル下のリンク --- */
  .sp-foot {
    width:100%; padding:0 20px calc(22px + env(safe-area-inset-bottom));
    text-align:center; cursor:default;
    font-size:11px; line-height:2.2; letter-spacing:.10em;
    color:rgba(233,226,214,.56);
  }
  .sp-foot a { color:rgba(233,226,214,.80); text-decoration:none; border-bottom:1px solid rgba(233,226,214,.20); }
  .sp-foot a:hover, .sp-foot a:focus-visible { color:#EDE6DA; border-color:rgba(233,226,214,.55); }
  /* 区切りは margin ではなく gap で置く。ソースの改行が余分なアキにならない */
  .sp-links { display:flex; flex-wrap:wrap; justify-content:center; align-items:baseline; gap:.3em .9em; }
  .sp-foot .sep { opacity:.30; }
  .sp-cred { margin-top:8px; font-size:10px; letter-spacing:.14em; color:rgba(233,226,214,.46); }

  #err {
    position:fixed; inset:0; display:none; place-items:center; padding:32px;
    text-align:center; color:#cfc9c0; font-size:14px; line-height:1.9;
    background:linear-gradient(#141018,#0a0a0f);
  }
  #err b { display:block; font-size:16px; margin-bottom:12px; color:#f0d9b8; }
  /* 動かない環境を行き止まりにしない */
  .err-links {
    display:flex; flex-wrap:wrap; justify-content:center; align-items:baseline; gap:.35em .9em;
    margin-top:26px; font-size:12px; letter-spacing:.08em;
  }
  .err-links a { color:rgba(233,226,214,.80); text-decoration:none; border-bottom:1px solid rgba(233,226,214,.28); }
  .err-links a:hover, .err-links a:focus-visible { color:#f0d9b8; border-color:#f0d9b8; }
  .err-links .sep { opacity:.30; }
