/* ============================================================
   GRIZE? — "Zora na vodi" design system
   Paleta iz subjekta: predzorno more (duboki teal), žar horizonta
   (jantar→ember), i chartreuse zaključan ISKLJUČIVO u fishfinder
   ekranu (trag + ribolovni lukovi). Stranica se prema dolje
   spušta u dubinu; uz rub ide sonarno dubinsko ravnalo.
   ============================================================ */
:root {
  --abyss: #04161e;
  --deep: #082430;
  --mid: #0c2e3c;
  --card: rgba(16, 51, 65, 0.72);
  --card-2: rgba(11, 40, 52, 0.72);
  --line: rgba(198, 228, 235, 0.10);
  --line-hi: rgba(255, 255, 255, 0.07);
  --ink: #e4f1f4;
  --dim: #98b8c0;
  --faint: #628792;
  --amber: #ffb454;
  --ember: #ff7e45;
  --amber-soft: rgba(255, 180, 84, 0.15);
  --trace: #c9f457;
  --trace-soft: rgba(201, 244, 87, 0.13);
  --warn: #ff7a6b;
  --ok: #6fd3a3;
  --radius: 18px;
  --font-display: "Bricolage Grotesque", "Arial Black", sans-serif;
  --font-body: "Instrument Sans", system-ui, sans-serif;
  --font-data: "IBM Plex Mono", ui-monospace, monospace;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  min-height: 100vh;
  background:
    linear-gradient(180deg,
      #0d3346 0%, #0a2b3c 16%, var(--deep) 34%, #061d28 62%, var(--abyss) 100%);
  background-attachment: fixed;
  overflow-x: hidden;
}
/* fini filmski grain preko svega */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 3; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

/* ---------- ZORA: hero scena (V2 — vidljiva, živa) ---------- */
.scene {
  position: absolute; inset: 0 0 auto 0; height: 560px; z-index: 0;
  overflow: hidden; pointer-events: none;
  background: linear-gradient(180deg, #0a1830 0%, #0c2438 34%, #12374a 52%, #0b2d3c 60%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 70%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 70%, transparent 100%);
}
/* zvijezde koje trnu pred zoru */
.stars { position: absolute; top: 26px; left: 6%; width: 2px; height: 2px; border-radius: 50%; background: #d7ecf2;
  box-shadow: 90px 14px #cfe7ee, 210px 58px #b9d8e0, 330px 8px #d7ecf2, 470px 44px #a9ccd6,
    600px 20px #d7ecf2, 700px 66px #b9d8e0, 830px 12px #cfe7ee, 950px 50px #a9ccd6,
    1060px 26px #d7ecf2, 1180px 60px #b9d8e0, 1290px 18px #cfe7ee, 150px 96px #8fb6c0,
    540px 104px #8fb6c0, 890px 92px #9fc2cc, 1240px 100px #8fb6c0, 40px 60px #9fc2cc;
  animation: twinkle 5.5s ease-in-out infinite; }
@keyframes twinkle { 0%,100% { opacity: 0.85; } 50% { opacity: 0.35; } }
/* sunce na horizontu: jaka jezgra + široki žar */
.scene-sun { position: absolute; left: 50%; top: 40px; width: 1100px; height: 640px; transform: translateX(-50%);
  background:
    radial-gradient(42% 30% at 50% 42%, rgba(255, 132, 66, 0.55), transparent 62%),
    radial-gradient(75% 55% at 50% 44%, rgba(255, 180, 84, 0.32), transparent 72%);
  animation: sunrise 9s ease-in-out infinite alternate; }
.sun-core { position: absolute; left: 50%; top: 218px; width: 150px; height: 76px; transform: translateX(-50%);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  background: radial-gradient(100% 140% at 50% 100%, #ffe9b0 0%, #ffc06a 46%, rgba(255, 140, 66, 0.55) 78%, transparent 100%);
  filter: blur(1.5px) drop-shadow(0 0 34px rgba(255, 170, 80, 0.75)); }
/* stup svjetla na vodi */
.sun-column { position: absolute; left: 50%; top: 292px; width: 120px; height: 270px; transform: translateX(-50%);
  background: linear-gradient(180deg, rgba(255, 190, 100, 0.42), rgba(255, 160, 74, 0.14) 55%, transparent 100%);
  -webkit-mask-image: repeating-linear-gradient(180deg, #000 0 7px, rgba(0,0,0,0.25) 7px 12px);
          mask-image: repeating-linear-gradient(180deg, #000 0 7px, rgba(0,0,0,0.25) 7px 12px);
  filter: blur(1px);
  animation: shimmer 3.8s ease-in-out infinite alternate; }
@keyframes shimmer { from { opacity: 0.75; transform: translateX(-50%) scaleX(0.94); } to { opacity: 1; transform: translateX(-50%) scaleX(1.06); } }
@keyframes sunrise { from { opacity: 0.8; } to { opacity: 1; } }
.waves { position: absolute; left: -4%; width: 216%; height: 96px; fill: currentColor; }
.waves.w1 { top: 268px; color: rgba(255, 158, 74, 0.22); animation: drift 24s linear infinite; }
.waves.w2 { top: 292px; color: rgba(146, 210, 224, 0.16); animation: drift 36s linear infinite reverse; }
.waves.w3 { top: 316px; color: rgba(8, 34, 45, 0.85); animation: drift 50s linear infinite; }
@keyframes drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* AMBIJENTALNI SONAR ispod površine — potpis na prvi pogled */
.hero-sonar { position: absolute; left: 0; right: 0; top: 336px; width: 100%; height: 200px; opacity: 0.85;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 55%, transparent 100%); }
.hs-grid line { stroke: rgba(148, 208, 220, 0.07); stroke-width: 1; }
.hs-trace { fill: none; stroke: var(--trace); stroke-width: 2.4; stroke-linecap: round;
  filter: drop-shadow(0 0 7px rgba(201, 244, 87, 0.8));
  stroke-dasharray: 1000; stroke-dashoffset: 1000;
  animation: hsdraw 11s ease-in-out infinite; }
@keyframes hsdraw {
  0% { stroke-dashoffset: 1000; opacity: 0; }
  6% { opacity: 0.9; }
  46% { stroke-dashoffset: 0; opacity: 0.9; }
  82% { stroke-dashoffset: 0; opacity: 0.9; }
  100% { stroke-dashoffset: 0; opacity: 0; } }
.hs-fish path { fill: none; stroke-width: 2.4; stroke-linecap: round; }
.hs-fish.hf1 path, .hs-fish.hf3 path { stroke: var(--trace); filter: drop-shadow(0 0 6px rgba(201, 244, 87, 0.9)); }
.hs-fish.hf2 path { stroke: var(--amber); filter: drop-shadow(0 0 6px rgba(255, 174, 69, 0.9)); }
.hs-fish { opacity: 0; animation: hsfish 11s ease-in-out infinite; }
.hs-fish.hf1 { animation-delay: 2.2s; }
.hs-fish.hf2 { animation-delay: 4.6s; }
.hs-fish.hf3 { animation-delay: 6.4s; }
@keyframes hsfish { 0%, 100% { opacity: 0; } 12% { opacity: 1; } 60% { opacity: 1; } 78% { opacity: 0; } }
.hs-ping { fill: none; stroke: var(--amber); stroke-width: 1.5; opacity: 0;
  transform-box: fill-box; transform-origin: center;
  animation: hsping 11s ease-out infinite; }
.hs-ping.p1 { animation-delay: 4.9s; }
.hs-ping.p2 { animation-delay: 2.5s; stroke: var(--trace); }
@keyframes hsping { 0%, 100% { opacity: 0; transform: scale(0.4); }
  4% { opacity: 0.9; transform: scale(0.5); } 16% { opacity: 0; transform: scale(3.2); } 17% { opacity: 0; } }

/* ---------- dubinsko ravnalo (sonar) ---------- */
.depth {
  position: fixed; left: 14px; top: 200px; bottom: 60px; width: 34px; z-index: 1;
  border-left: 1px solid rgba(198, 228, 235, 0.12);
  background:
    repeating-linear-gradient(180deg,
      rgba(198, 228, 235, 0.14) 0 1px, transparent 1px 12.5%);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 0 0 0 7px; pointer-events: none;
}
.depth span { font: 500 0.6rem var(--font-data); color: rgba(152, 184, 192, 0.5); transform: translateY(-0.5em); }
.depth span:last-child { transform: translateY(0.2em); }
@media (max-width: 1180px) { .depth { display: none; } }

/* The insets are not decoration on Android. index.html asks for
   viewport-fit=cover, which is what lets the app paint edge to edge behind
   the status and navigation bars — and nothing in this stylesheet ever paid
   that back. Measured on an S23 Ultra: env(safe-area-inset-top) is 34 px and
   the header sat 16 px from the top, so the clock and the signal bars were
   drawn over the title and the tagline; at the foot, 48 px of gesture bar lay
   over the last control on the page. On the website every env() here resolves
   to 0, so this costs the browser build nothing. */
.shell {
  position: relative; z-index: 2; max-width: 880px; margin: 0 auto;
  padding: calc(26px + env(safe-area-inset-top)) calc(18px + env(safe-area-inset-right))
           calc(70px + env(safe-area-inset-bottom)) calc(18px + env(safe-area-inset-left));
}

/* ---------- header ---------- */
.top { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 34px 0 236px; }
.brand h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.7rem, 8vw, 4.4rem);
  letter-spacing: -0.035em;
  margin: 0; line-height: 0.95;
  text-shadow: 0 2px 30px rgba(4, 22, 30, 0.6);
}
.brand h1 .q {
  background: linear-gradient(160deg, var(--amber) 20%, var(--ember) 85%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 14px rgba(255, 148, 69, 0.55));
  animation: qpulse 4.5s ease-in-out infinite;
  display: inline-block;
}
@keyframes qpulse {
  0%, 100% { filter: drop-shadow(0 0 10px rgba(255, 148, 69, 0.4)); }
  50% { filter: drop-shadow(0 0 22px rgba(255, 148, 69, 0.75)); }
}
.brand p { margin: 12px 0 0; color: #b9d3da; max-width: 44ch; font-size: 0.98rem; text-wrap: balance; text-shadow: 0 1px 12px rgba(4, 22, 30, 0.8); }
.head-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.lang { display: flex; gap: 2px; background: rgba(4, 22, 30, 0.6); border: 1px solid var(--line); border-radius: 999px; padding: 3px; backdrop-filter: blur(8px); }
.lang button { background: none; border: 0; color: var(--dim); font: 600 0.8rem var(--font-data); padding: 5px 12px; border-radius: 999px; cursor: pointer; }
.lang button.on { background: var(--amber); color: #2a1604; }

/* ---------- panels: staklo nad dubinom ---------- */
.panel {
  position: relative;
  background: linear-gradient(180deg, var(--card), var(--card-2));
  border: 1px solid var(--line);
  border-top-color: var(--line-hi);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 18px;
  box-shadow: 0 24px 60px rgba(2, 12, 17, 0.45);
  backdrop-filter: blur(10px);
}
.panel h2 { font-family: var(--font-display); font-size: 1.35rem; font-weight: 700; margin: 0 0 4px; letter-spacing: -0.01em; }
.hint { color: var(--dim); font-size: 0.9rem; margin: 0 0 16px; }

/* ---------- mode toggle ---------- */
.mode { display: inline-flex; gap: 2px; background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 12px; padding: 3px; margin-bottom: 18px; }
.mode button { background: none; border: 0; color: var(--dim); font: 600 0.92rem var(--font-body); padding: 9px 20px; border-radius: 9px; cursor: pointer; transition: color 0.15s; }
.mode button.on { background: linear-gradient(180deg, var(--mid), #0a2836); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-hi), 0 2px 8px rgba(0,0,0,0.3); }

/* ---------- inputs ---------- */
.inputs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.inputs.two { grid-template-columns: repeat(2, 1fr); }
.in-btn {
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 14px;
  padding: 18px 8px; color: var(--ink); cursor: pointer; font: 600 0.9rem var(--font-body);
  transition: border-color 0.2s, transform 0.12s, box-shadow 0.2s; text-align: center;
}
.in-btn:hover { border-color: rgba(255, 180, 84, 0.55); box-shadow: 0 0 24px rgba(255, 160, 74, 0.12); transform: translateY(-1px); }
.in-btn:active { transform: scale(0.98); }
.in-btn svg { width: 27px; height: 27px; stroke: var(--amber); fill: none; stroke-width: 1.7; }
.in-btn.primary { border-color: rgba(255, 174, 69, 0.5); background: var(--amber-soft); }

.search-wrap { position: relative; margin-top: 12px; }
#search {
  width: 100%; background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink); font: 400 0.95rem var(--font-body); padding: 12px 15px; outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
#search:focus { border-color: var(--amber); box-shadow: 0 0 0 3px rgba(255, 180, 84, 0.12); }
#search-results {
  position: absolute; z-index: 900; top: calc(100% + 5px); left: 0; right: 0;
  background: #0d3140; border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  box-shadow: 0 18px 40px rgba(2, 12, 17, 0.55);
}
.search-item { display: block; width: 100%; text-align: left; background: none; border: 0; color: var(--ink); padding: 11px 15px; cursor: pointer; font: 400 0.92rem var(--font-body); }
.search-item:hover { background: var(--amber-soft); }

/* ---------- saved spots ---------- */
#saved-row { margin-top: 18px; }
#saved-title { font: 600 0.72rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.1em; display: block; margin-bottom: 9px; }
#saved-spots { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 999px;
  color: var(--ink); padding: 7px 8px 7px 15px; cursor: pointer; font: 500 0.86rem var(--font-body);
  transition: border-color 0.15s;
}
.chip:hover { border-color: var(--amber); }
.chip-x { color: var(--faint); font-size: 1rem; padding: 0 5px; border-radius: 50%; }
.chip-x:hover { color: var(--warn); }

/* ---------- map ---------- */
#map-section { padding: 0; overflow: hidden; }
#map { height: 340px; filter: saturate(0.85) contrast(1.02); }
.map-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 18px; }
#map-hint { color: var(--dim); font-size: 0.88rem; margin: 0; }

/* ---------- buttons ---------- */
.btn {
  background: linear-gradient(180deg, #ffc36e, var(--amber) 55%, #f0973f);
  border: 0; border-radius: 12px; color: #2a1604;
  font: 700 0.92rem var(--font-body); padding: 11px 20px; cursor: pointer;
  box-shadow: 0 4px 18px rgba(255, 160, 74, 0.28), inset 0 1px 0 rgba(255,255,255,0.35);
  transition: transform 0.12s, box-shadow 0.2s, filter 0.15s;
}
.btn:hover { filter: brightness(1.06); box-shadow: 0 6px 26px rgba(255, 160, 74, 0.4), inset 0 1px 0 rgba(255,255,255,0.35); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.4; cursor: default; box-shadow: none; }
.btn.ghost { background: rgba(4, 22, 30, 0.55); color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.btn.ghost:hover { border-color: var(--amber); filter: none; }
.btn.mini { padding: 7px 15px; font-size: 0.82rem; }

/* ---------- results ---------- */
#loading {
  display: flex; align-items: center; gap: 12px;
  color: var(--amber); font: 500 0.95rem var(--font-data); padding: 14px 2px;
}
#loading::before {
  content: ""; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid rgba(255, 180, 84, 0.25); border-top-color: var(--amber);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.results-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 34px 0 6px; }
.results-head h2 { font-family: var(--font-display); font-size: 1.65rem; margin: 0; letter-spacing: -0.02em; }
#spot-coords { font: 400 0.78rem var(--font-data); color: var(--faint); display: block; margin-top: 2px; }
#save-bar { display: flex; gap: 8px; margin: 10px 0 0; width: 100%; }
#save-name { flex: 1; background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 12px; color: var(--ink); padding: 10px 13px; font: 400 0.9rem var(--font-body); outline: none; }
#save-name:focus { border-color: var(--amber); }

#legend { display: flex; flex-wrap: wrap; gap: 16px; color: var(--faint); font: 400 0.78rem var(--font-body); margin: 10px 0 16px; }
#legend span { display: inline-flex; align-items: center; gap: 6px; }
.lg { width: 14px; height: 5px; border-radius: 3px; display: inline-block; }
.lg-major { background: var(--amber); }
.lg-minor { background: var(--dim); }
.lg-twi { background: linear-gradient(90deg, transparent, rgba(255,174,69,.5)); height: 12px; width: 12px; border-radius: 3px; }
.lg-sim { background: repeating-linear-gradient(90deg, var(--amber) 0 5px, transparent 5px 9px); }

/* ---------- day cards ---------- */
#days { display: grid; gap: 16px; }
.day {
  background: linear-gradient(180deg, var(--card), var(--card-2));
  border: 1px solid var(--line); border-top-color: var(--line-hi);
  border-radius: var(--radius); padding: 18px 20px 15px;
  box-shadow: 0 20px 50px rgba(2, 12, 17, 0.4);
  backdrop-filter: blur(10px);
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.55s ease, transform 0.55s ease, border-color 0.3s;
}
.day.in { opacity: 1; transform: none; }
.day.today { border-color: rgba(255, 180, 84, 0.28); }
.day:hover { border-color: rgba(255, 180, 84, 0.35); }
.day-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.day-head h3 { font-family: var(--font-display); font-size: 1.2rem; margin: 0; text-transform: capitalize; letter-spacing: -0.01em; }
.day-date { font: 400 0.78rem var(--font-data); color: var(--faint); }
.day-meta { display: flex; align-items: center; gap: 15px; flex-wrap: wrap; justify-content: flex-end; }
.moon { font-size: 1.1rem; }
.moon em, .rate em { font: 400 0.72rem var(--font-body); color: var(--dim); font-style: normal; margin-left: 5px; }
.rate { display: inline-flex; align-items: center; gap: 2px; }
.fish { width: 19px; height: 12px; display: block; }
.f-on .fish path { fill: var(--amber); filter: drop-shadow(0 0 3px rgba(255, 174, 69, 0.6)); }
.f-off .fish path { fill: rgba(152, 184, 192, 0.22); }

/* ---------- FISHFINDER (signature) ---------- */
.trace {
  width: 100%; height: 110px; display: block;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(20, 66, 82, 0.5), transparent 70%),
    #041016;
  border-radius: 12px; border: 1px solid rgba(201, 244, 87, 0.12);
  box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.5), 0 0 22px rgba(201, 244, 87, 0.05);
}
.tr-grid { stroke: rgba(148, 200, 210, 0.08); stroke-width: 1; }
.tr-area { fill: var(--trace-soft); }
.tr-line { fill: none; stroke: var(--trace); stroke-width: 2; stroke-linejoin: round; filter: drop-shadow(0 0 5px rgba(201, 244, 87, 0.7)); }
.tr-sim { fill: none; stroke: var(--amber); stroke-width: 1.8; stroke-dasharray: 5 4; opacity: 0.95; filter: drop-shadow(0 0 4px rgba(255, 174, 69, 0.5)); }
.tr-twilight { fill: rgba(255, 174, 69, 0.13); }
.tr-major { fill: var(--amber); }
.tr-minor { fill: var(--dim); opacity: 0.6; }
.tr-now { stroke: var(--warn); stroke-width: 1.2; stroke-dasharray: 3 3; }
.tr-nowtxt { fill: var(--warn); font: 600 9px var(--font-data); }
.tr-tick { fill: var(--faint); font: 400 9px var(--font-data); }
.tr-fish { fill: none; stroke-width: 2; stroke-linecap: round; }
.tr-fish.f-sol { stroke: var(--trace); filter: drop-shadow(0 0 4px rgba(201, 244, 87, 0.8)); }
.tr-fish.f-sim { stroke: var(--amber); filter: drop-shadow(0 0 4px rgba(255, 174, 69, 0.8)); }
.tr-scan rect { fill: rgba(201, 244, 87, 0.05); }
.tr-scan line { stroke: rgba(201, 244, 87, 0.35); stroke-width: 1.5; }

/* ---------- windows + weather ---------- */
.wins { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 13px 0 10px; }
.wins-label { font: 600 0.74rem var(--font-data); color: var(--dim); text-transform: uppercase; letter-spacing: 0.07em; }
.win { background: var(--amber-soft); border: 1px solid rgba(255, 174, 69, 0.4); color: var(--amber); border-radius: 9px; padding: 4px 11px; font: 600 0.92rem var(--font-data); }
.win.none { background: none; border-color: var(--line); color: var(--faint); font: 400 0.85rem var(--font-body); }
.wins.sims .win.sim { border-color: rgba(255, 174, 69, 0.55); background: rgba(255, 174, 69, 0.1); }
.win.sim em { font: 400 0.78rem var(--font-body); color: var(--dim); font-style: normal; margin-left: 4px; }
.day-wx { display: flex; flex-wrap: wrap; gap: 8px 18px; border-top: 1px solid var(--line); padding-top: 11px; margin-top: 2px; }
.wx { font: 400 0.82rem var(--font-data); color: var(--dim); }
.wx b { color: var(--faint); font-weight: 500; margin-right: 4px; }

/* ---------- catches ---------- */
.catches-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.catches-head .hint { margin-bottom: 0; max-width: 52ch; }
.catches-head .btn { flex: none; }
#catch-form { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 18px; }
.photo-btn {
  display: flex; align-items: center; gap: 11px; cursor: pointer;
  background: var(--amber-soft); border: 1px solid rgba(255, 174, 69, 0.5);
  border-radius: 13px; padding: 14px 17px; font: 600 0.9rem var(--font-body); color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.2s;
}
.photo-btn:hover { border-color: var(--amber); box-shadow: 0 0 22px rgba(255, 160, 74, 0.14); }
.photo-btn svg { width: 24px; height: 24px; stroke: var(--amber); fill: none; stroke-width: 1.7; flex: none; }
.photo-status { font-size: 0.85rem; margin: 9px 0 0; min-height: 1em; }
.photo-status.ok { color: var(--ok); }
.photo-status.warn { color: var(--amber); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 15px 0 0; }
.form-grid label { display: flex; flex-direction: column; gap: 5px; font: 600 0.72rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.08em; }
.form-grid input, .txt {
  width: 100%; background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink); font: 400 0.95rem var(--font-body); padding: 10px 13px; outline: none;
  color-scheme: dark; transition: border-color 0.15s;
}
.form-grid input:focus, .txt:focus { border-color: var(--amber); }
.txt { margin-top: 10px; }
.mini-label { font: 600 0.72rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.08em; margin: 15px 0 6px; }
#catch-map { height: 240px; border-radius: 12px; border: 1px solid var(--line); filter: saturate(0.85); }
.form-actions { display: flex; gap: 10px; margin-top: 15px; }
.gps-help { margin-top: 15px; font-size: 0.85rem; color: var(--dim); }
.gps-help summary { cursor: pointer; color: var(--faint); font: 600 0.8rem var(--font-body); }
.gps-help p { margin: 8px 0 0; line-height: 1.6; }
#catch-filter { max-width: 260px; margin-top: 15px; }
#catch-list { margin-top: 13px; display: grid; gap: 9px; }
.catch-item {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
  background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 13px; padding: 13px 15px;
  transition: border-color 0.15s;
}
.catch-item:hover { border-color: rgba(255, 180, 84, 0.3); }
.catch-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.catch-main b { font-size: 0.97rem; text-transform: capitalize; }
.catch-when { font: 400 0.78rem var(--font-data); color: var(--faint); }
.catch-fp { font: 400 0.8rem var(--font-data); color: var(--dim); }
.catch-note { font-size: 0.82rem; color: var(--faint); font-style: italic; }
.catch-actions { display: flex; gap: 6px; flex: none; }
.mini-btn {
  background: rgba(16, 51, 65, 0.8); border: 1px solid var(--line); border-radius: 9px;
  color: var(--dim); font: 600 0.78rem var(--font-body); padding: 5px 11px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.mini-btn:hover { border-color: var(--amber); color: var(--ink); }
.mini-btn.del:hover { border-color: var(--warn); color: var(--warn); }
.catch-vis { display: flex; gap: 8px; margin-top: 8px; }
.catch-vis .txt { margin-top: 0; width: auto; padding: 6px 10px; font-size: 0.82rem; }

/* ---------- empty / toast / footer ---------- */
#empty { position: relative; text-align: center; padding: 58px 20px; overflow: hidden;
  background: radial-gradient(120% 90% at 50% 0%, rgba(20, 66, 82, 0.45), transparent 70%), rgba(4, 16, 22, 0.7);
  border: 1px solid rgba(201, 244, 87, 0.14); border-radius: var(--radius);
  box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.5); }
#empty::before { content: ""; position: absolute; top: 0; bottom: 0; width: 90px;
  background: linear-gradient(90deg, transparent, rgba(201, 244, 87, 0.07) 70%, rgba(201, 244, 87, 0.28));
  animation: emptyscan 5.5s linear infinite; }
@keyframes emptyscan { from { left: -100px; } to { left: 100%; } }
#empty h2 { font-family: var(--font-display); color: var(--dim); margin: 0 0 6px; }
#empty p { color: var(--faint); margin: 0 auto; max-width: 44ch; }
.toast {
  /* Above the gesture bar, not under it: the toast carries the Undo for the
     one-tap blank, and a recovery control half-hidden by the navigation bar
     is one somebody stops reaching for. */
  position: fixed; z-index: 1200; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(90px);
  background: #0d3140; border: 1px solid var(--line); border-left: 3px solid var(--amber);
  color: var(--ink); border-radius: 12px; padding: 13px 19px; max-width: min(90vw, 480px);
  font-size: 0.9rem; opacity: 0; transition: transform 0.28s cubic-bezier(.2,.9,.3,1.2), opacity 0.25s; pointer-events: none;
  box-shadow: 0 14px 44px rgba(2, 12, 17, 0.6);
}
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
.toast.warn { border-left-color: var(--warn); }
.toast.ok { border-left-color: var(--ok); }
/* The toast itself stays click-through so it never blocks the map or a button
   underneath it. A child can opt back in, which is exactly what an action
   needs — without this the Undo renders and does nothing. */
.toast-action {
  pointer-events: auto; margin-left: 14px; vertical-align: middle;
  background: transparent; border: 1px solid var(--amber); color: var(--amber);
  /* 44px, not the 32px the type would suggest: this is a recovery control
     tapped in a hurry, outdoors, often with wet or cold hands. */
  border-radius: 999px; padding: 5px 15px; min-height: 44px; cursor: pointer;
  font: 600 0.74rem var(--font-data); text-transform: uppercase; letter-spacing: 0.07em;
}
.toast-action:hover { background: var(--amber-soft); }
.toast-action:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* Sample size sits next to the success rate it supports, quieter than the
   number but never hidden — the percentage is only meaningful with it. */
.win-sample { color: var(--faint); font-size: 0.82em; }
footer.site { margin-top: 48px; border-top: 1px solid var(--line); padding-top: 20px; color: var(--faint); font-size: 0.78rem; }
footer.site p { margin: 0 0 8px; }

/* ---------- modals ---------- */
.backdrop {
  position: fixed; inset: 0; z-index: 1100; background: rgba(3, 12, 17, 0.78);
  display: flex; align-items: center; justify-content: center; padding: 18px;
  backdrop-filter: blur(5px);
}
.modal {
  position: relative; width: min(94vw, 440px); max-height: 88vh; overflow: auto;
  background: linear-gradient(180deg, #103546, #0b2b39);
  border: 1px solid var(--line); border-top-color: var(--line-hi);
  border-radius: var(--radius); padding: 24px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
  animation: modalin 0.25s cubic-bezier(.2,.9,.3,1.15);
}
@keyframes modalin { from { opacity: 0; transform: translateY(14px) scale(0.98); } to { opacity: 1; transform: none; } }
.modal h3 { font-family: var(--font-display); margin: 0 0 6px; font-size: 1.25rem; }
.modal-x { position: absolute; top: 10px; right: 12px; background: none; border: 0; color: var(--faint); font-size: 1.4rem; cursor: pointer; line-height: 1; }
.modal-x:hover { color: var(--ink); }
.btn.oauth { display: block; width: 100%; margin-top: 10px; background: #fff; color: #1a1a1a; box-shadow: 0 4px 16px rgba(0,0,0,0.3); }
.btn.oauth.fb { background: #1877f2; color: #fff; }

/* ---------- friends ---------- */
.friend-add { display: flex; gap: 8px; margin-top: 12px; }
.friend-add .txt { margin-top: 0; flex: 1; }
#relations { margin-top: 14px; display: grid; gap: 6px; }
.rel-item { display: flex; align-items: center; gap: 10px; background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 11px; padding: 10px 14px; font-size: 0.9rem; }
.rel-item .mini-btn { margin-left: auto; }
.tag { font: 600 0.68rem var(--font-data); color: var(--dim); border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px; }
.tag.mut { color: var(--ok); border-color: rgba(111, 211, 163, 0.4); }
.feed-h { font-family: var(--font-display); font-size: 1.05rem; margin: 22px 0 8px; color: var(--dim); }
#feed { display: grid; gap: 9px; }
.feed-item { border-left: 2px solid rgba(255, 174, 69, 0.35); }

/* ---------- share modal ---------- */
.share-opts { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 6px 0 4px; }
.share-opt { display: inline-flex; align-items: center; gap: 7px; font-size: 0.9rem; cursor: pointer; }
.share-opt input { accent-color: var(--amber); width: 16px; height: 16px; }
.seg { display: inline-flex; gap: 2px; background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 11px; padding: 3px; margin: 4px 0; }
.seg button { background: none; border: 0; color: var(--dim); font: 600 0.82rem var(--font-body); padding: 7px 14px; border-radius: 8px; cursor: pointer; }
.seg button.on { background: var(--amber); color: #2a1604; }
#share-preview {
  background: rgba(4, 22, 30, 0.75); border: 1px solid var(--line); border-radius: 12px;
  padding: 13px 15px; font: 400 0.82rem var(--font-data); color: var(--dim);
  white-space: pre-wrap; margin: 4px 0 10px; max-height: 180px; overflow: auto;
}
.share-channels { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* ---------- a11y & motion ---------- */
button:focus-visible, input:focus-visible, select:focus-visible, .in-btn:focus-visible, summary:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .toast, .day { transition: none; }
  .day { opacity: 1; transform: none; }
  .scene-sun, .waves, .brand h1 .q { animation: none; }
  .tr-scan { display: none; }
}

/* ---------- mobile ---------- */
@media (max-width: 560px) {
  .shell {
    padding: calc(16px + env(safe-area-inset-top)) calc(13px + env(safe-area-inset-right))
             calc(56px + env(safe-area-inset-bottom)) calc(13px + env(safe-area-inset-left));
  }
  /* The hero used to own the whole first screen: 34+236 px of header padding
     under a four-line tagline meant "Where are you fishing?" — the only thing
     a new user actually needs — began on the second screenful. The tagline is
     now one line (see i18n tagline) and the scene is scaled to match, so the
     location card is reachable without scrolling. */
  .top { padding: 14px 0 116px; }
  .scene { height: 232px; }
  .scene-sun { top: 34px; }
  .waves.w1 { top: 128px; } .waves.w2 { top: 150px; } .waves.w3 { top: 172px; }
  .brand h1 { font-size: clamp(2.1rem, 9vw, 3rem); }
  .inputs, .inputs.two { grid-template-columns: 1fr; }
  .in-btn { flex-direction: row; justify-content: flex-start; padding: 14px 17px; }
  .day-head { flex-direction: column; }
  .day-meta { justify-content: flex-start; }
  #map { height: 280px; }
  .catches-head { flex-direction: column; }
  .form-grid { grid-template-columns: 1fr; }
  .catch-item { flex-direction: column; }
  .share-channels { grid-template-columns: 1fr 1fr; }
}
.chip-name { cursor: pointer; }
.brand h1 .q { text-shadow: none; }

/* KRITIČNO: atribut hidden uvijek pobjeđuje display pravila klasa.
   Bez ovoga modal backdrop (display:flex) prekrije i zamuti cijelu stranicu. */
[hidden] { display: none !important; }

.nocfg-note { background: rgba(255, 174, 69, 0.1); border: 1px solid rgba(255, 174, 69, 0.35);
  border-radius: 11px; padding: 11px 14px; font-size: 0.85rem; color: var(--amber); margin: 4px 0 10px; }
.modal.nocfg .btn.oauth, .modal.nocfg .friend-add { opacity: 0.35; pointer-events: none; }

/* mobile V2 hero */
@media (max-width: 560px) {
  .scene { height: 470px; }
  .scene-sun { top: -20px; }
  .sun-core { top: 168px; width: 110px; height: 58px; }
  .sun-column { top: 224px; height: 220px; width: 90px; }
  .waves.w1 { top: 214px; } .waves.w2 { top: 236px; } .waves.w3 { top: 258px; }
  .hero-sonar { top: 276px; height: 180px; }
  .top { padding: 18px 0 196px; }
}
@media (prefers-reduced-motion: reduce) {
  .stars, .sun-column, .hs-trace, .hs-fish, .hs-ping { animation: none; }
  .hs-trace { stroke-dashoffset: 0; opacity: 0.85; }
  .hs-fish { opacity: 0.9; }
}

/* ============================================================
   Baitprint v2 additions — tabs, sessions/blanks, stats, checklist,
   tackle box, alerts, tides, safety. Same design system as above.
   ============================================================ */

/* ---------- units + tabs ---------- */
.btn.primary { font-size: 0.95rem; padding: 12px 22px; }
.tabs {
  display: flex; gap: 4px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 14px;
  padding: 4px; margin-bottom: 18px; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none; background: none; border: 0; color: var(--dim); font: 600 0.86rem var(--font-body);
  padding: 10px 16px; border-radius: 10px; cursor: pointer; white-space: nowrap; transition: color 0.15s, background 0.15s;
}
.tab.on { background: linear-gradient(180deg, var(--mid), #0a2836); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-hi); }
.tab:hover:not(.on) { color: var(--ink); }
/* Croatian labels are longer than the English ones the padding was chosen
   for. Measured on a 384 px phone: the strip was 497 px wide and "Obavijesti"
   began at x=387 — entirely off-screen, with "Oprema" ending at 383 so the
   row looked complete and finished. The strip does scroll, but nothing said
   so, and the tab that carries the paid feature was the one nobody could see.
   Tighter padding and slightly smaller type fit all five; the 44 px height
   is unchanged, since that is the part a cold hand needs. */
@media (max-width: 430px) {
  .tabs { gap: 2px; }
  .tab { padding: 12px 7px; font-size: 0.76rem; }
}
.tabpanel { animation: modalin 0.2s ease; }

/* ---------- platform toggle ---------- */
.platform-row { margin-left: 10px; }
.platform-row select { margin-left: 8px; padding: 8px 10px; }
@media (max-width: 700px) { .mode { flex-wrap: wrap; } .platform-row { margin-left: 0; margin-top: 8px; } }

/* ---------- offline banner ---------- */
.offline-banner {
  background: rgba(255, 174, 69, 0.12); border: 1px solid rgba(255, 174, 69, 0.4);
  color: var(--amber); border-radius: 12px; padding: 10px 15px; font-size: 0.86rem; margin: 0 0 14px;
}

/* Plan panel — always present in the Alerts tab, in every state. */
.plan-panel {
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line);
  border-radius: 13px; padding: 15px 17px; margin: 0 0 16px;
}
.plan-panel.is-pro { border-color: rgba(255, 180, 84, 0.35); }
.plan-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.plan-head b { color: var(--ink); font-size: 1rem; }
.plan-status {
  font: 600 0.72rem var(--font-data); text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--amber); background: var(--amber-soft); border-radius: 999px; padding: 3px 10px;
}
.plan-panel:not(.is-pro) .plan-status { color: var(--faint); background: rgba(152, 184, 192, 0.1); }
.plan-body { margin: 9px 0 13px; font-size: 0.87rem; color: var(--dim); line-height: 1.6; }
/* Language picker in the account modal. */
.account-lang {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 14px; font-size: 0.88rem; color: var(--dim);
}
/* Measured on a 384 px viewport in Croatian: with flex-shrink 0 the select
   took the width of its longest option and ran 19 px past the modal and off
   the screen. It may shrink now, and it keeps the 44 px the rest of the
   controls promise — a select is a tap target like any other, and at 39 px it
   was the shortest thing in the app. */
.account-lang select { flex: 0 1 auto; min-width: 0; max-width: 60%; min-height: 44px; padding: 9px 11px; }

.plan-manage { margin: 12px 0 0; font-size: 0.82rem; color: var(--faint); line-height: 1.55; }
/* Cancel is a legitimate thing to want. Muted, not hidden, and not styled to
   punish — a cancel button people cannot find becomes a chargeback. */
.btn.ghost.danger { color: var(--warn); border-color: rgba(255, 122, 107, 0.35); }
.btn.ghost.danger:hover { background: rgba(255, 122, 107, 0.09); }
.btn[disabled] { opacity: 0.6; pointer-events: none; }
.plan-panel .billing-actions { margin-left: 0; }

/* Trial state. Three tones because the three moments are genuinely different:
   the start is good news and earns colour, the last days are a warning, the
   end is a statement of fact. */
.billing-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  border: 1px solid var(--line); border-left-width: 3px; border-radius: 12px;
  padding: 12px 16px; margin: 0 0 14px; font-size: 0.88rem;
  line-height: 1.6; color: var(--dim); background: rgba(4, 22, 30, 0.5);
}
.billing-banner b { color: var(--ink); }
.billing-banner.good { border-left-color: var(--ok); }
.billing-banner.warn { border-left-color: var(--amber); }
.billing-banner.info { border-left-color: var(--faint); }
.billing-actions { display: flex; gap: 8px; margin-left: auto; }
.btn.small { padding: 7px 13px; font-size: 0.84rem; min-height: 38px; }
@media (max-width: 560px) {
  .billing-actions { margin-left: 0; width: 100%; }
  .billing-actions .btn { flex: 1; }
}

/* Personal layer not ready yet. Quieter than the offline banner — this is
   information about what is coming, not a fault, and it must not compete with
   the forecast it sits above. */
.pattern-locked {
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line);
  border-left: 3px solid var(--amber); border-radius: 12px;
  padding: 11px 15px; margin: 0 0 14px; font-size: 0.86rem;
  line-height: 1.6; color: var(--dim);
}
.pattern-locked b { color: var(--ink); }

/* ---------- confidence + progress ---------- */
.progress-box {
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line); border-radius: 13px;
  padding: 13px 16px; margin: 4px 0 18px; font-size: 0.88rem; color: var(--dim);
}
.progress-box b { color: var(--ink); }
.progress-bar { height: 6px; border-radius: 4px; background: rgba(198, 228, 235, 0.1); margin-top: 8px; overflow: hidden; }
.progress-bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--trace), var(--amber)); border-radius: 4px; }
.conf-badge { display: inline-flex; align-items: center; gap: 5px; font: 600 0.72rem var(--font-data); border-radius: 999px; padding: 3px 10px; text-transform: uppercase; letter-spacing: 0.04em; }
.conf-badge.low { color: var(--faint); background: rgba(152, 184, 192, 0.1); }
.conf-badge.building { color: var(--amber); background: var(--amber-soft); }
.conf-badge.confident { color: var(--ok); background: rgba(111, 211, 163, 0.14); }
.pattern-row.low-n { opacity: 0.45; }

/* ---------- log actions + session form ---------- */
.log-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 6px; }
.log-actions .btn small, .btn-sub { display: block; font: 400 0.72rem var(--font-body); opacity: 0.75; margin-top: 2px; }
#session-form { margin-top: 20px; border-top: 1px solid var(--line); padding-top: 18px; display: grid; gap: 4px; }
.form-grid.three { grid-template-columns: 1fr 1fr 1fr; }
#session-map { height: 220px; border-radius: 12px; border: 1px solid var(--line); filter: saturate(0.85); margin: 4px 0 10px; }
.chip-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 6px 0; }
.chip.select { padding: 6px 14px; font-size: 0.83rem; cursor: pointer; }
.chip.select.on { border-color: var(--amber); background: var(--amber-soft); color: var(--amber); }
.seg#outcome-seg { margin: 6px 0 10px; }
.catches-editor { display: grid; gap: 12px; margin: 10px 0; }
.catch-row {
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line); border-radius: 13px; padding: 14px;
  display: grid; gap: 8px;
}
.catch-row-head { display: flex; justify-content: space-between; align-items: center; }
.catch-row-head b { font: 700 0.85rem var(--font-body); color: var(--dim); text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.72rem; }
.suggest-row { display: flex; flex-wrap: wrap; gap: 6px; }
.suggest-chip { background: var(--amber-soft); border: 1px solid rgba(255, 174, 69, 0.4); color: var(--amber); border-radius: 999px; padding: 5px 12px; font: 600 0.8rem var(--font-body); cursor: pointer; }
.bait-match-hint { font-size: 0.82rem; color: var(--dim); }
@media (max-width: 700px) { .form-grid.three { grid-template-columns: 1fr; } }

/* ---------- filters + session list ---------- */
.filters-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 12px; }
.filters-row .txt { margin-top: 0; width: auto; }
#session-list { display: grid; gap: 9px; }
.session-item {
  background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 13px; padding: 13px 15px;
}
.session-item.blank { border-style: dashed; opacity: 0.85; }
.session-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.session-head b { font-size: 0.95rem; }
.session-meta { font: 400 0.78rem var(--font-data); color: var(--faint); }
.session-outcome { font-size: 0.88rem; color: var(--faint); margin-top: 3px; font-style: italic; }
.session-catches { margin-top: 8px; display: grid; gap: 6px; }
.session-catches .catch-mini { font-size: 0.85rem; color: var(--dim); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.session-actions { display: flex; gap: 6px; margin-top: 8px; }
.thumb { width: 44px; height: 44px; border-radius: 8px; object-fit: cover; border: 1px solid var(--line); }

/* ---------- day card additions: pattern row, tide, safety ---------- */
.wins.pattern .win.conf-low { color: var(--faint); border-color: var(--line); background: none; }
.win.tide { background: rgba(146, 210, 224, 0.12); border-color: rgba(146, 210, 224, 0.35); color: #bfe3ec; }
.safety-banner {
  background: rgba(255, 122, 107, 0.12); border: 1px solid rgba(255, 122, 107, 0.4);
  color: var(--warn); border-radius: 10px; padding: 8px 13px; font-size: 0.82rem; margin: 8px 0 0;
}

/* ---------- stats ---------- */
.sub-h { font-family: var(--font-display); font-size: 1.05rem; margin: 24px 0 10px; color: var(--dim); }
.sub-h:first-of-type { margin-top: 4px; }
#bests-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.best-card { background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 13px; padding: 13px 15px; }
.best-card h4 { margin: 0 0 8px; font-family: var(--font-display); font-size: 1rem; text-transform: capitalize; }
.best-card div { font: 400 0.8rem var(--font-data); color: var(--dim); margin-top: 3px; }
#patterns-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.pattern-group h4 { font: 600 0.76rem var(--font-data); text-transform: uppercase; letter-spacing: 0.06em; color: var(--faint); margin: 0 0 8px; }
/* 70px, not 40: the percentage and its sample count sit on one line, and
   "83% 12/12" is the widest that line gets. At 40 the count wrapped mid-word;
   at 56 the longest pair still broke onto a second line while its neighbours
   did not, which is worse than either - the eye reads the ragged one as a
   different kind of row. */
.pattern-row { display: grid; grid-template-columns: 70px 1fr 70px; align-items: center; gap: 8px; font-size: 0.82rem; margin-bottom: 5px; }
.pattern-row .lbl { color: var(--dim); text-transform: capitalize; }
.pattern-bar { height: 8px; border-radius: 4px; background: rgba(198, 228, 235, 0.08); overflow: hidden; }
.pattern-bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--trace), var(--amber)); }
.pattern-row .pct { text-align: right; font: 400 0.76rem var(--font-data); color: var(--faint); }
#season-chart { display: grid; gap: 6px; }
.season-row { display: grid; grid-template-columns: 70px 1fr 90px; align-items: center; gap: 10px; font-size: 0.82rem; }
.season-bar { display: flex; height: 12px; border-radius: 4px; overflow: hidden; background: rgba(198, 228, 235, 0.08); }
.season-bar .c { background: var(--trace); } .season-bar .b { background: rgba(255, 122, 107, 0.5); }

/* ---------- checklist ---------- */
.checklist-toolbar { display: flex; gap: 8px; margin-bottom: 14px; }
.checklist-toolbar .txt { margin-top: 0; flex: 1; }
#checklist-items { display: grid; gap: 6px; margin-bottom: 12px; }
.check-item { display: flex; align-items: center; gap: 10px; background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line); border-radius: 10px; padding: 9px 13px; }
.check-item input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--amber); flex: none; }
.check-item span { flex: 1; font-size: 0.9rem; }
.check-item.done span { color: var(--faint); text-decoration: line-through; }
.check-item .mini-btn { flex: none; }

/* ---------- tackle box ---------- */
#tacklebox-form { margin: 14px 0; display: grid; gap: 10px; border-top: 1px solid var(--line); padding-top: 14px; }
.tacklebox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-top: 14px; }
.lure-card { background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 13px; padding: 10px; text-align: center; }
.lure-card img, .lure-swatch { width: 100%; aspect-ratio: 1; border-radius: 10px; object-fit: cover; margin-bottom: 8px; background: rgba(198, 228, 235, 0.08); display: flex; align-items: center; justify-content: center; font-size: 0.7rem; color: var(--faint); }
.lure-card b { display: block; font-size: 0.85rem; }
.lure-card div { font: 400 0.72rem var(--font-data); color: var(--faint); margin-top: 3px; }

/* ---------- alerts ---------- */
#alerts-list { display: grid; gap: 10px; }
.alert-row { background: rgba(4, 22, 30, 0.55); border: 1px solid var(--line); border-radius: 13px; padding: 14px 16px; }
.alert-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.alert-settings { display: grid; gap: 8px; margin-top: 10px; grid-template-columns: 1fr 1fr; }
.alert-settings label { display: flex; flex-direction: column; gap: 4px; font: 600 0.7rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.06em; }
.alert-settings input, .alert-settings select { background: rgba(4, 22, 30, 0.65); border: 1px solid var(--line); border-radius: 9px; color: var(--ink); padding: 7px 10px; font: 400 0.85rem var(--font-body); color-scheme: dark; }
.switch { position: relative; width: 42px; height: 24px; flex: none; }
.switch input { opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch .track { position: absolute; inset: 0; background: rgba(198, 228, 235, 0.14); border-radius: 999px; transition: background 0.15s; pointer-events: none; }
.switch .track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--ink); transition: transform 0.15s; }
.switch input:checked + .track { background: var(--amber); }
.switch input:checked + .track::after { transform: translateX(18px); background: #2a1604; }

/* ---------- footer legal links ---------- */
.legal-links { margin-top: 10px; }
.legal-links a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--line); }
.legal-links a:hover { color: var(--amber); border-bottom-color: var(--amber); }

/* ---------- account modal ---------- */
.account-identity {
  font: 400 0.9rem var(--font-data); color: var(--dim);
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line);
  border-radius: 11px; padding: 11px 14px; margin: 4px 0 16px; word-break: break-word;
}
.account-actions { display: grid; gap: 8px; }
.account-actions .btn { width: 100%; }
.btn.ghost.danger { color: var(--warn); border-color: rgba(255, 122, 107, 0.35); }
.btn.ghost.danger:hover { border-color: var(--warn); background: rgba(255, 122, 107, 0.08); }
/* Deletion is deliberately the least prominent control in the sheet — findable
   when wanted, never the thing your thumb lands on by accident. */
.link-danger {
  display: block; width: 100%; margin-top: 18px; padding: 10px;
  background: none; border: 0; border-top: 1px solid var(--line);
  color: var(--faint); font: 400 0.82rem var(--font-body); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.link-danger:hover { color: var(--warn); }
.delete-list { margin: 10px 0 16px; padding-left: 20px; color: var(--dim); font-size: 0.87rem; }
.delete-list li { margin-bottom: 5px; }
.btn.danger-solid {
  background: linear-gradient(180deg, #ff8f7f, #e8503c);
  color: #2a0c07; box-shadow: 0 4px 18px rgba(232, 80, 60, 0.28);
}
.btn.danger-solid:disabled { opacity: 0.4; box-shadow: none; }

/* ---------- bulk import wizard ---------- */
.import-wizard { margin-top: 20px; border-top: 1px solid var(--line); padding-top: 18px; display: grid; gap: 4px; }
.import-wizard .progress-bar { margin: 8px 0 4px; }
#import-clusters { display: grid; gap: 12px; margin: 10px 0; }
.import-cluster {
  background: rgba(4, 22, 30, 0.5); border: 1px solid var(--line); border-radius: 13px; padding: 14px;
  display: grid; gap: 8px; transition: opacity 0.15s;
}
.import-cluster.skipped { opacity: 0.45; }
.import-cluster.located { border-color: rgba(111, 211, 163, 0.45); }
.import-result {
  background: rgba(111, 211, 163, 0.1); border: 1px solid rgba(111, 211, 163, 0.35);
  border-left: 3px solid var(--ok); border-radius: 12px;
  padding: 13px 16px; margin: 16px 0 0; font-size: 0.9rem; color: var(--ink); line-height: 1.6;
}
.import-result.has-problem { background: rgba(255, 174, 69, 0.1); border-color: rgba(255, 174, 69, 0.4); border-left-color: var(--amber); }
.import-species-line { color: var(--dim); font: 600 0.85rem var(--font-data); margin-top: 8px; }

/* A species the app guessed from the photo, not one the angler stood behind.
   Amber rather than green: this is "check me", not "confirmed". */
.species-badge {
  font: 600 0.62rem var(--font-data); text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--amber); background: rgba(255, 174, 69, 0.12);
  border: 1px solid rgba(255, 174, 69, 0.32); border-radius: 999px;
  padding: 1px 7px; vertical-align: 1px; white-space: nowrap;
}
.hint.suggested { color: var(--amber); }

/* --- log view switch: list / photos / map --- */
.view-switch { display: flex; gap: 6px; margin: 0 0 12px; flex-wrap: wrap; }
.view-btn {
  flex: 1 1 auto; min-width: 88px; min-height: 44px; /* thumb-sized on a phone */
  background: transparent; border: 1px solid var(--line); border-radius: 10px;
  color: var(--dim); font: 600 0.82rem var(--font-data); letter-spacing: 0.04em;
  cursor: pointer; padding: 10px 14px; transition: color .15s, border-color .15s, background .15s;
}
.view-btn:hover { color: var(--ink); border-color: var(--ok); }
.view-btn.is-on { color: var(--abyss); background: var(--ok); border-color: var(--ok); }

/* --- catch gallery --- */
.catch-gallery {
  display: grid; gap: 12px; margin-top: 4px;
  /* auto-fill keeps one column on a phone and fills the width on a laptop
     without a media query per breakpoint */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.gtile {
  display: flex; flex-direction: column; text-align: left; padding: 0; overflow: hidden;
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer; color: inherit; font: inherit;
  transition: border-color .15s, transform .15s;
}
.gtile:hover { border-color: var(--ok); transform: translateY(-2px); }
.gtile-img {
  position: relative; display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; background: rgba(255,255,255,0.03); overflow: hidden;
}
/* Overlays the placeholder rather than replacing it, so a photo that has gone
   missing from storage falls back to readable text instead of a blank box. */
.gtile-img img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; background: var(--deep);
}
.gtile-none { color: var(--faint); font: 600 0.7rem var(--font-data); letter-spacing: 0.06em; }
.gtile-cap { display: flex; flex-direction: column; gap: 3px; padding: 9px 11px 11px; }
.gtile-cap b { color: var(--ink); font-size: 0.88rem; font-weight: 600; }
.gtile-cap small { color: var(--dim); font-size: 0.74rem; }
.gtile .species-badge { margin-left: 5px; }

/* --- catch map --- */
.catch-map-wrap { margin-top: 4px; }
#catch-map { height: 420px; border-radius: 12px; border: 1px solid var(--line); }
@media (max-width: 640px) { #catch-map { height: 320px; } }

/* --- photo inside the edit dialog --- */
.edit-photo-wrap { margin: 0 0 16px; }
.edit-photo-wrap img {
  display: block; width: 100%; max-height: 260px; object-fit: contain;
  border-radius: 12px; border: 1px solid var(--line); background: rgba(0,0,0,0.25);
}
.edit-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px;
  font: 600 0.72rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.08em; }
.edit-field .txt { margin-top: 0; }
.import-progress { font: 600 0.85rem var(--font-data); color: var(--dim); margin: 6px 0 12px; }
.import-progress.all-done { color: var(--ok); }
.cluster-where { font: 600 0.86rem var(--font-body); color: var(--ok); min-height: 1.2em; }
.cluster-picks { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.pick-label { font: 600 0.72rem var(--font-data); color: var(--faint); text-transform: uppercase; letter-spacing: 0.06em; }
.cluster-map-toggle summary { cursor: pointer; color: var(--faint); font-size: 0.83rem; padding: 4px 0; }
.cluster-map-toggle summary:hover { color: var(--ink); }
.cluster-map-toggle .import-cluster-map { margin-top: 8px; }
.apply-all-btn { justify-self: start; }
.import-cluster-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 0.88rem; color: var(--dim); }
.import-cluster-map { height: 160px; border-radius: 10px; border: 1px solid var(--line); filter: saturate(0.85); }
.import-cluster-map.placed { border-color: rgba(255, 174, 69, 0.45); }

/* ---------- mobile ---------- */
@media (max-width: 560px) {
  .tabs { margin: 0 -13px 16px; border-radius: 0; padding: 4px 13px; border-left: 0; border-right: 0; }
  .alert-settings { grid-template-columns: 1fr; }
  #bests-list, .tacklebox-grid { grid-template-columns: 1fr 1fr; }
  /* One column, unlike the cards beside it. Two columns left each pattern row
     70px of label, 56px of number and about 28px of bar - a yellow dash that
     could not be compared with the dash above it, which is the entire job of
     a bar. Full width gives it roughly 200px. */
  #patterns-grid { grid-template-columns: 1fr; }
  /* Three across, always. "Fotografije" is wide enough that flex-wrap put
     "Karta" alone on a second full-width row, which reads as a separate
     control rather than the third of three. */
  .view-switch { display: grid; grid-template-columns: repeat(3, 1fr); }
  .view-btn { min-width: 0; padding: 10px 6px; }
  /* 44px is the smallest reliably tappable target — the default button
     padding lands at ~41px, which is a miss-prone edge on a phone held
     one-handed on a boat. */
  .btn, .tab, .mini-btn { min-height: 44px; }
  .mini-btn { padding-left: 14px; padding-right: 14px; }
}

/* Saving badge on the annual button. Small and inside the button on purpose:
   a bare larger number reads as more expensive, so the reason it is the
   default has to travel with it. */
.save-badge {
  display: inline-block; margin-left: 7px; padding: 2px 7px;
  border-radius: 999px; font: 600 0.72em var(--font-data);
  background: rgba(4, 22, 30, 0.22); color: inherit; vertical-align: baseline;
}
.btn.ghost .save-badge { background: var(--amber-soft); }

/* Export. Wraps rather than shrinking: three buttons with real labels do not
   fit one phone line, and a truncated "Everything (JS…" is worse than a
   second row. */
.export-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 10px; }
.export-actions .btn[disabled] { opacity: .45; cursor: default; }
#export-count { margin: 0; }

/* Served for readers that do not run JavaScript — search engines, link
   preview bots, payment-provider domain scans. On the website app.js moves it
   below the panels when applyStatic() runs and setSpot() hides it (see the
   comment there for why it is moved, not hidden). Styled anyway: a scan that
   renders the page should find something legible, not unstyled text stacked
   on the scene layers.

   In the Android app it is never shown at all. The inline script in
   index.html's head marks <html class="is-native"> before the first paint;
   without this rule the intro flashed above the forecast on every cold start
   until the module ran. */
.is-native .static-intro { display: none; }
/* Same cold start, second flash: until app.js has run, the header and tab bar
   show the English source strings from the HTML, and on a Croatian phone they
   switched language in front of the angler. In the app only, the shell stays
   invisible until app.js adds "app-ready" (a 4 s fallback in index.html makes
   sure it never stays hidden). The scene - sky, sun and water - is outside
   .shell and still paints, so the wait looks like the app's own opening image
   rather than a blank screen. */
.is-native:not(.app-ready) .shell { visibility: hidden; }
.static-intro {
  max-width: 68ch;
  margin: 0 auto 22px;
  padding: 18px 22px;
  background: var(--panel, rgba(13, 44, 58, .82));
  border: 1px solid var(--line, rgba(198, 228, 235, .14));
  border-radius: 14px;
  font-size: .95rem;
  line-height: 1.6;
}
.static-intro p { margin: 0 0 10px; }
.static-intro p:last-child { margin-bottom: 0; font-size: .85rem; opacity: .75; }

/* ---- cold-start import: the offer, where the gap is admitted ---- */

/* Sits inside #pattern-locked, directly under the sentence saying there is
   not enough of the angler's own history yet. */
.btn.locked-import { margin-top: 12px; }

/* The wizard's signed-out caveat: visible, not alarming. It says what an
   account would add, before any time is spent picking photos. */
.import-signedout {
  border-left: 2px solid var(--amber, #ffb454);
  padding-left: 10px;
  opacity: .9;
}

/* Shown after a signed-out import, next to the angler's freshly rebuilt
   history — the one moment an account is worth something to them. */
.import-account-offer {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line, rgba(198, 228, 235, .14));
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: .9rem;
}

/* An empty log puts the import first in the DOM order too, not just visually:
   keyboard and screen-reader users reach the useful button first. */
.log-actions.import-first { flex-wrap: wrap; }
.log-actions.import-first #btn-import-photos { order: -1; }

/* ---- the cold-start offer: first thing on the first tab ---- */

/* Deliberately louder than the panel below it. The trial - and therefore the
   subscription - cannot begin until four outings exist, and a photo import is
   the only way that happens on day one rather than in two months. */
.panel.import-hero {
  border-color: var(--amber, #ffb454);
  background:
    linear-gradient(180deg, rgba(255, 180, 84, .10), rgba(255, 180, 84, 0) 60%),
    var(--panel, #0d2c3a);
}
.panel.import-hero h2 { margin-top: 0; }
.panel.import-hero p { color: var(--dim, #a8c4cc); max-width: 62ch; }
.import-hero-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 14px;
}

/* "Not now" must read as a way out, not as a second offer competing with the
   first — so it is a link, not a button. */
.btn.link {
  background: none;
  border: none;
  padding: 6px 2px;
  color: var(--faint, #7fa0aa);
  text-decoration: underline;
  font-weight: 400;
}
.btn.link:hover { color: var(--ink, #e4f1f4); }

/* The collapsed state. Still one click away, no longer taking the screen. */
.import-hero-mini {
  display: block;
  width: 100%;
  margin: 0 0 14px;
  padding: 9px 12px;
  background: none;
  border: 1px dashed var(--line, rgba(198, 228, 235, .14));
  border-radius: 10px;
  color: var(--faint, #7fa0aa);
  font: inherit;
  font-size: .88rem;
  text-align: left;
  cursor: pointer;
}
.import-hero-mini:hover {
  color: var(--ink, #e4f1f4);
  border-color: var(--amber, #ffb454);
}


/* ============================================================
   First visit, on a phone.

   The decorative scene reserves 196px under the header so the app does not
   sit on top of the sonar. On a desktop that is a nice opening; on an 812px
   phone it pushed "Import my catches" down to y=791 - on the screen,
   technically, and below the fold in every way that counts. That button is
   the whole argument for this app over a generic solunar table, and a
   first-time visitor was scrolling past a fish animation to reach it.

   So the scene is compressed while the offer is up, and only then: body
   gets .offer-first from renderImportOffer(). Somebody who has already
   imported gets the full opening, because for them the animation is the
   first thing worth showing and no CTA is competing with it. The desktop is
   untouched, where the space was never the problem.

   Last in the file on purpose - it has to win over the two earlier
   max-width:560px blocks that set these same properties.
   ============================================================ */
@media (max-width: 560px) {
  body.offer-first .scene { height: 340px; }
  body.offer-first .scene-sun { top: -60px; }
  body.offer-first .sun-core { top: 120px; width: 92px; height: 46px; }
  body.offer-first .sun-column { top: 166px; height: 150px; width: 76px; }
  body.offer-first .waves.w1 { top: 158px; }
  body.offer-first .waves.w2 { top: 176px; }
  body.offer-first .waves.w3 { top: 194px; }
  body.offer-first .hero-sonar { top: 202px; height: 130px; }
  body.offer-first .top { padding: 14px 0 92px; }
}


/* The diagnostics panel. Monospaced and dense on purpose: it is read once, by
   somebody being asked to relay what it says, and every row has to survive
   being retyped or photographed accurately. */
.diag { margin-top: 18px; border: 1px solid var(--line, #16323d); border-radius: 10px; padding: 10px 12px; }
.diag > summary { cursor: pointer; font-size: 13px; opacity: 0.75; }
.diag-body { margin-top: 10px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; }
.diag-body > div { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0;
  border-bottom: 1px solid var(--line, #16323d); }
.diag-body > div:last-child { border-bottom: 0; }
.diag-body span { opacity: 0.7; }
.diag-body b { font-weight: 600; text-align: right; word-break: break-all; }

/* ============================================================
   Touch targets.

   Measured on the device: twenty-five controls came back under 44px on their
   short side - the mode and platform toggles at 36, the export buttons at 38,
   every delete × at 36 wide, the saved-spot chips at 35 tall. Small targets
   are a nuisance in a warm room and a real failure on a boat in February, with
   wet hands, gloves, or a phone held one-handed while the other holds a rod.

   44px is the floor both platforms' guidelines settle on and what WCAG 2.2
   recommends. Applied with min-height and padding rather than by changing font
   sizes, so nothing about the layout's proportions moves: the buttons grow
   into space they already had.

   Last in the file so it wins over the rules it is correcting, all of which
   set padding on the same elements.
   ============================================================ */
/* .mode is the segmented control the mode and platform switches live in.
   An earlier version of this block aimed at .seg, which is a different control
   elsewhere in the file - the rule was valid, applied to nothing, and the
   buttons stayed at 36px while the fix looked done. Read off the live DOM
   this time rather than guessed from the stylesheet. */
.mode button, .seg button {
  min-height: 44px;
  padding-top: 0;
  padding-bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.chip { min-height: 44px; }
.mini-btn {
  min-height: 44px;
  min-width: 44px;
  padding-top: 0;
  padding-bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Icon-only buttons need the width too: a + or a x is a narrow glyph, and
   min-height alone leaves a 39px-wide target. */
.btn.small, .btn.mini {
  min-height: 44px;
  min-width: 44px;
  padding-top: 0;
  padding-bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* The diagnostics summary is a real tap target that opens the panel, not a
   caption - it was 20px tall. */
.diag > summary { min-height: 44px; display: flex; align-items: center; }

/* The test-push result, under the button that produced it. It was a span
   beside the button, so a three-line failure wrapped around it in an L and
   began on the button's own line — hard to read at exactly the moment it
   matters most. */
.alerts-test { margin-bottom: 8px; }
.alerts-test-result { margin: 0 0 4px; max-width: 60ch; }

/* ---------- phone: the tab strip is pinned to the bottom ----------
   It used to be a static strip under the header, and it scrolled away with
   everything else. Measured on a 375x812 viewport: the forecast panel is
   ~5 200 px tall with all seven day cards open, so from Friday's card the
   strip sat 498 px above the top of the screen — reaching Log meant scrolling
   the whole week back up, every time. On the phone it is now fixed to the
   bottom edge, where the thumb already is; on desktop nothing scrolls far
   enough for that to be worth the screen height, so the strip stays put.
   Appended at the end of the file on purpose: the mobile block near line 508
   sets .shell's padding as a shorthand, and this has to win over it. */
@media (max-width: 700px) {
  .tabs {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    margin: 0; border-radius: 0; border-width: 1px 0 0;
    overflow-x: hidden;
    background: rgba(4, 22, 30, 0.94);
    backdrop-filter: blur(12px);
    padding: 4px calc(4px + env(safe-area-inset-right))
             calc(4px + env(safe-area-inset-bottom)) calc(4px + env(safe-area-inset-left));
  }
  /* Equal columns rather than a scrolling row. The Croatian labels are the
     constraint — "Statistika" and "Obavijesti" are ten characters against a
     75 px column — so the font drops and the label ellipsises rather than
     pushing a tab off the edge, which is what the horizontal strip did. */
  .tabs .tab {
    flex: 1 1 0; min-width: 0; min-height: 52px;
    padding: 10px 2px; font-size: 0.7rem; text-align: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* Clears the fixed strip so the last control on a panel is not under it. */
  .shell { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }
}

/* ---------- session form: the optional half ----------
   Everything an outing does not need in order to be recorded. Closed by
   default; the summary is a real tap target, not a caption. */
.session-more { margin: 14px 0 4px; border: 1px solid var(--line); border-radius: 12px; background: rgba(4, 22, 30, 0.4); }
.session-more > summary {
  min-height: 44px; display: flex; align-items: center; gap: 8px;
  padding: 0 14px; cursor: pointer; color: var(--dim); font: 600 0.86rem var(--font-body);
  list-style: none;
}
.session-more > summary::-webkit-details-marker { display: none; }
.session-more > summary::before { content: '+'; font: 700 1.1rem var(--font-data); color: var(--amber); }
.session-more[open] > summary::before { content: '−'; }
.session-more[open] > summary { color: var(--ink); }
.session-more > *:not(summary) { margin-left: 14px; margin-right: 14px; }
.session-more > *:last-child { margin-bottom: 14px; }

/* The mini import offer now appears as soon as an outing is logged, not only
   after "not now", so it sits over the header artwork far more often than it
   used to. With background:none it read as loose text floating on the waves.
   It is also a real tap target and was 35 px tall. */
.import-hero-mini {
  min-height: 44px;
  padding: 0 14px;
  background: rgba(4, 22, 30, 0.62);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* A month whose outings have no start and end time shows an em dash where the
   catch-per-hour would be, rather than a number derived from a floor. Muted so
   it reads as "not available" and not as a value. */
.season-row .no-rate { font-style: normal; color: var(--faint, #7fa0aa); cursor: help; }
