/* Climbs showcase grid — visually identical to the public routes-index.php
   card grid, but scoped to the in-app #climbs-panel overlay. shell.js gives
   the panel its fixed position + 14px padding; everything here is the
   centred content column and the cards. */

#climbs-panel {
  /* shell.js sets display/position/etc inline; only colour is ours. */
  color: var(--txt);
}

/* Sub-tab strip (TKF-406) — the nav item is Rides; Climbs is the category
   inside it. Deliberately the same visual language as .analysis-tabs and
   .pc-viewtabs, and deliberately NOT the same class, for the reason pacer.css
   spells out: reaching into another feature's stylesheet couples two features
   that are only loaded together by accident. The tokens are the shared thing.
   Keep the three in step by hand if the Analysis strip is restyled.

   Full width and left aligned, like .analysis-tabs (TKF-410): the panel
   already gives 14px of padding, and analysis.css carries no layout-level
   max-width at all. The rule the strip is inside IS the pattern. */
.rides-tabs {
  display: flex;
  gap: 2px;
  margin: 0 0 20px;
  border-bottom: 1px solid var(--bg3);
}
.rides-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--dim);
  font-family: var(--font-text);
  font-size: var(--fs-base);
  font-weight: 500;
  padding: 8px 16px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.rides-tab:hover { color: var(--txt); }
/* The other two strips drop the ring on :focus AND :focus-visible, which
   leaves a keyboard user with no focus indicator at all. Dropping it on
   :focus only is visually identical for a mouse (no ring on click) and keeps
   the ring where it is actually needed. */
.rides-tab:focus { outline: none; }
.rides-tab:focus-visible { outline: 2px solid var(--amber-ink); outline-offset: -2px; }
.rides-tab.active { color: var(--txt-hi); border-bottom-color: var(--amber-ink); }

/* The host the sub-tabs swap content inside (TKF-411). No box of its own —
   the views bring their own head and grid — it exists so showView() can clear
   one node without touching the strip above it. */
.rides-view { display: block; }

/* ── Velodrome tile (TKF-411; rideable since TKF-407) ──────────────────────
   A velodrome is not a geo route, so api/climb-thumb.php has nothing to draw.
   A drawn glyph takes the thumbnail slot at the same 2:1 box as .climbs-thumb
   and .climbs-upload-icon, so card heights stay aligned in the grid. */
.climbs-glyph {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  flex-shrink: 0;
  background: var(--bg2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--amber-ink);
}
/* Three concentric ovals — rail, measurement line, inner edge. Sized to sit
   inside the box with air around it rather than cropping to cover, because a
   track reads as a track only when the whole oval is visible. */
.climbs-glyph-art {
  width: 72%;
  height: auto;
  opacity: 0.45;
}

.climbs-head {
  margin: 0 0 24px;
}
.climbs-head h1 {
  margin: 4px 0 8px;
  font-size: var(--fs-xl);
  font-weight: 600;
  color: var(--txt);
}
.climbs-lede {
  color: var(--dim);
  margin: 0;
  max-width: 720px;
  line-height: 1.55;
}

/* Full-bleed inside the panel's padding (TKF-410). auto-fill + minmax was
   already doing the work; the 1100px cap was the only thing stopping the
   cards from using the width, and it centred them against every other page. */
.climbs-grid {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.climbs-card-wrap { position: relative; }

/* height:100% + flex-column makes the card fill its grid row (wraps stretch
   by default, but a block-layout card sits at its content height inside).
   The body is `flex:1` so when a card has less text than the tallest in the
   row (e.g. the "Your own GPX" card with no stats/region lines) it absorbs
   the difference and outer card heights stay aligned. */
.climbs-card {
  background: var(--bg1);
  border: 1px solid var(--bdr);
  border-radius: 8px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: border-color .15s;
}
.climbs-card:hover { border-color: var(--amber-ink); }
.climbs-body { flex: 1; }

/* Thumb is now a wrapper div that owns the 2:1 box; the <img> inside fills
   absolutely so it can't impose its own intrinsic ratio. Matches the upload
   card's icon structure (.climbs-upload-icon + absolute SVG bg) for identical
   sizing in the grid. */
.climbs-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  flex-shrink: 0;                  /* hold size inside the flex-column card */
  background: var(--bg2);
  overflow: hidden;
}
.climbs-thumb-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.climbs-body { padding: 12px 14px 14px; }

.climbs-title {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--txt);
  margin: 0 0 6px;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.climbs-stats {
  font-size: var(--fs-xs);
  color: var(--dim);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.climbs-stats b {
  color: var(--amber-ink);
  font-weight: 600;
  margin-left: 3px;
}

.climbs-region {
  font-size: var(--fs-xs);
  color: var(--dim2);
  margin-top: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.climbs-blurb {
  font-size: var(--fs-sm);
  color: var(--dim);
  margin: 8px 0 0;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Play badge — "this card opens the ride simulator". */
.climbs-play {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg0) 62%, transparent);
  color: var(--amber-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  transition: background .15s, transform .1s;
}
.climbs-card-wrap:hover .climbs-play { background: color-mix(in srgb, var(--bg0) 85%, transparent); }
.climbs-card-wrap:active .climbs-play { transform: scale(0.9); }

.climbs-empty {
  background: var(--bg1);
  border: 1px solid var(--bdr);
  border-radius: 8px;
  padding: 44px 20px;
  text-align: center;
  color: var(--dim);
  font-size: var(--fs-base);
}

/* "Your own GPX" card — top-left of the grid, same dimensions as a curated
   card but rendered as a <button> (file picker, not navigation). Dashed
   border distinguishes "or, bring your own" from the curated set. Button
   defaults are reset so it sits flush with the <a> cards. */
.climbs-card-upload {
  border-style: dashed;
  background: transparent;
  width: 100%;
  padding: 0;                      /* body provides its own padding */
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.climbs-card-upload:hover { background: var(--bg1); }
.climbs-card-upload:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}
.climbs-upload-icon {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;             /* matches .climbs-thumb so card height aligns */
  flex-shrink: 0;                  /* same flex pin as .climbs-thumb */
  background: var(--bg2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--amber-ink);
}
/* Mountain silhouette + wavy road — the climbs nav icon enlarged to fill the
   thumb-sized area. preserveAspectRatio="xMidYMid slice" on the SVG itself
   means the artwork crops to cover the box at any card width without
   stretching the strokes. */
.climbs-upload-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.22;
}
.climbs-upload-arrow {
  position: relative;              /* sits above the bg silhouette */
  width: 56px;
  height: 56px;
  opacity: 0.85;
}
.climbs-card-upload:hover .climbs-upload-bg    { opacity: 0.35; }
.climbs-card-upload:hover .climbs-upload-arrow { opacity: 1; }

/* "Load in Climbs" banner (TKF-378): a workout is stashed and this grid is
   the climb picker. Sits between the heading and the cards. */
.climbs-workout {
  margin: 0 0 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  border: 1px solid color-mix(in srgb, var(--amber) 45%, transparent);
  background: color-mix(in srgb, var(--amber) 10%, var(--bg1));
  border-radius: 12px;
}
.climbs-workout-text { flex: 1; min-width: 0; }
.climbs-workout-eyebrow {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--amber-ink);
}
.climbs-workout-line {
  margin-top: 2px;
  font-size: var(--fs-md);
  color: var(--txt);
}
.climbs-workout-line b { font-weight: 600; }
.climbs-workout-hint {
  margin: 4px 0 0;
  color: var(--dim);
  font-size: var(--fs-sm);
  line-height: 1.5;
}
.climbs-workout-remove {
  flex: none;
  font: inherit;
  font-size: var(--fs-sm);
  padding: 7px 12px;
  border-radius: 8px;
  border: 1px solid var(--bdr2);
  background: var(--bg2);
  color: var(--txt);
  cursor: pointer;
}
.climbs-workout-remove:hover { border-color: var(--amber); }

/* Group rides (TKF-439): a panel of its own under the heading — its title,
   its one button, the rider's rides as rows — rather than an eyebrow and a
   line of text with the button in the page's far corner.
   Capped, with the loaded-workout banner above it: the cards below hug the
   left (auto-fill), so a full-width panel put its button and every row's
   Ride / Invite a whole screen away on a wide display. 820 px holds a row —
   the time, a long title, two buttons — and sits with the 720 px lede. */
.climbs-workout, .climbs-group { max-width: 820px; box-sizing: border-box; }
.climbs-group {
  margin: 0 0 24px;
  padding: 16px 18px;
  border: 1px solid var(--bdr2);
  background: var(--bg1);
  border-radius: 12px;
}
.climbs-group-new { margin-top: 12px; }
.climbs-group-title { margin: 0; font-size: var(--fs-md); font-weight: 600; color: var(--txt); }
.climbs-group-lede { margin: 2px 0 0; color: var(--dim); font-size: var(--fs-sm); line-height: 1.5; }
.climbs-group-list { list-style: none; margin: 0; padding: 0; }
.climbs-group-list:not(:empty) { margin-top: 14px; border-top: 1px solid var(--bdr); }
.climbs-gr {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--bdr);
}
.climbs-gr:last-child { border-bottom: 0; padding-bottom: 2px; }
.climbs-gr-when { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.climbs-gr-when span { font-size: var(--fs-xs); letter-spacing: .08em; text-transform: uppercase; color: var(--dim2); }
.climbs-gr-when b { font-size: var(--fs-lg); font-weight: 700; color: var(--txt); font-variant-numeric: tabular-nums; }
.climbs-gr-when i { font-style: normal; font-size: var(--fs-sm); color: var(--amber); }
.climbs-gr-when.live b {
  padding: 3px 11px;
  border-radius: 999px;
  font-size: var(--fs-sm);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--green);
  background: color-mix(in srgb, var(--green) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
.climbs-gr-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; color: var(--txt); text-decoration: none; }
.climbs-gr-main b { font-size: var(--fs-md); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.climbs-gr-main span { color: var(--dim); font-size: var(--fs-sm); }
.climbs-gr-main:hover b { color: var(--amber); }
.climbs-gr-actions { display: flex; gap: 8px; }
.climbs-btn {
  flex: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 8px;
  border: 1px solid var(--bdr2);
  background: var(--bg2);
  color: var(--txt);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.climbs-btn:hover { border-color: var(--amber); }
.climbs-btn.primary { background: var(--amber); border-color: var(--amber); color: #111; }
.climbs-btn.primary:hover { filter: brightness(1.08); }
.climbs-session-form {
  margin: 14px 0 0;
  padding: 16px 18px;
  border: 1px solid var(--bdr);
  background: var(--bg0);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 560px;
}
.climbs-session-form h2 { margin: 0; font-size: var(--fs-md); }
.climbs-session-row { display: grid; grid-template-columns: 70px 1fr; gap: 12px; align-items: center; }
.climbs-session-row > span { color: var(--dim); font-size: var(--fs-sm); }
.climbs-session-row select, .climbs-session-row input {
  font: inherit; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--bdr2);
  background: var(--bg2); color: var(--txt); min-width: 0;
}
.climbs-session-when { display: flex; flex-wrap: wrap; gap: 8px; }
.climbs-session-go { align-self: flex-start; }
.climbs-session-err { margin: 0; color: var(--red); font-size: var(--fs-sm); min-height: 1em; }
@media (max-width: 640px) {
  .climbs-gr { grid-template-columns: 96px minmax(0, 1fr); }
  .climbs-gr-actions { grid-column: 1 / -1; }
}

/* ── Worlds (TKF-476) ─────────────────────────────────────────────────────── */
/* The card art is the look's own sky over a ridge (inline SVG), in the
   glyph's 2:1 box, so the cards line up with the rest of the grid. */
.worlds-art { color: inherit; }
.worlds-art-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Length and terrain for every loop: two small segmented rows above the grid */
.worlds-opts { display: flex; flex-wrap: wrap; gap: 12px 28px; margin: 0 0 20px; }
.worlds-opt { display: flex; align-items: center; gap: 10px; }
.worlds-opt-label { color: var(--dim); font-size: var(--fs-sm); }
.worlds-seg { display: inline-flex; border: 1px solid var(--bdr); border-radius: 8px; overflow: hidden; }
.worlds-chip {
  background: var(--bg1); color: var(--dim); border: none; border-right: 1px solid var(--bdr);
  font-family: var(--font-text); font-size: var(--fs-sm); padding: 6px 12px; cursor: pointer;
}
.worlds-chip:last-child { border-right: none; }
.worlds-chip:hover { color: var(--txt); }
.worlds-chip:focus { outline: none; }
.worlds-chip:focus-visible { outline: 2px solid var(--amber-ink); outline-offset: -2px; }
.worlds-chip.active { background: var(--bg2); color: var(--txt-hi); box-shadow: inset 0 -2px 0 var(--amber-ink); }

/* The workout world's look chips (TKF-484): along the foot of its card, over
   the body's padding, outside the card's link. */
.climbs-world .climbs-body { padding-bottom: 84px; }   /* two rows of chips */
.worlds-looks { position: absolute; left: 14px; right: 14px; bottom: 12px; display: flex; flex-wrap: wrap; gap: 6px; }
.worlds-look {
  font-family: var(--font-text); font-size: var(--fs-xs); color: var(--dim);
  background: var(--bg1); border: 1px solid var(--bdr); border-radius: 999px; padding: 3px 9px; cursor: pointer;
}
.worlds-look:hover { color: var(--txt); }
.worlds-look:focus { outline: none; }
.worlds-look:focus-visible { outline: 2px solid var(--amber-ink); outline-offset: 1px; }
.worlds-look.active { color: var(--txt-hi); border-color: var(--amber-ink); }

