/* ══════════════════════════════════════
   Active Knitting Page
══════════════════════════════════════ */

.at-shell { z-index: 102; }

/* ── Topbar ── */
.at-topbar {
  height: 44px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 12px;
  gap: 8px;
  flex-shrink: 0;
  box-shadow: var(--shadow);
  /* Guarantees every control (critically the Prev/Next row buttons at the
     end — the most-used controls in the whole app) stays reachable no
     matter how many topbar controls have accumulated or how narrow the
     screen is. Without this, once the row's fixed-width children (back
     button, chips, reference toggle, color picker, opacity, more-options)
     exceed the viewport width even with .at-tb-name compressed to nothing,
     the trailing buttons were pushed off-screen with no way to reach them
     at all on a narrow phone — reported live by a new beta user. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.at-tb-back {
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-mid);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  transition: all 0.12s;
}
.at-tb-back:hover { border-color: var(--ink-mid); color: var(--ink); }

.at-tb-name {
  font-size: var(--fs-12);
  color: var(--ink-mid);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* Offline indicator (rowbie#57, ADR-0009) — text, not an icon/badge, per
   the ADR's explicit "readable at a glance, not another symbol to parse."
   flex-shrink:0 so it never gets squeezed to nothing; .at-tb-name (the one
   topbar element designed to absorb space, via flex:1 + ellipsis) gives up
   room to it instead. */
.at-tb-offline {
  font-size: var(--fs-12);
  font-weight: 600;
  color: var(--warn);
  white-space: nowrap;
  flex-shrink: 0;
}

.at-tb-chip {
  height: 30px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0 8px;
  display: flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
}

.at-chip-label {
  font-size: var(--fs-9);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-light);
}

.at-chip-num {
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-15);
  font-weight: 600;
  color: var(--ink);
}

.at-chip-sep {
  font-size: var(--fs-12);
  color: var(--ink-light);
}

.at-chip-total {
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-12);
  color: var(--ink-light);
}

.at-chip-rep {
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-12);
  font-weight: 700;
  color: var(--accent);
}

/* ── Chart zone ── */
.at-chart-zone {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
}

.at-chart-area {
  flex: 1;
  min-height: 0;
  /* hidden, not auto — panning is no longer native browser scroll (see
     .at-chart-zoom-inner below and active_tracking.rs's zoom/pan signal
     setup). Two CSS-only attempts to smooth the native-scroll approach's
     "jumps once zoomed in further" (a transition here, then swapping
     justify-content:center for margin:auto on the child) both failed —
     the actual cause was relying on native overflow-scroll at all: a
     scrollable flex container recomputes its scroll origin the instant
     zoomed content starts to genuinely overflow, snapping the view in one
     frame no matter how the CSS around it is tuned (issue #30). Moving to
     transform-based pan (matching the PDF picker's crop/setup overlays)
     removes native scroll from this element entirely, so there's no
     scroll origin left to recompute. */
  overflow: hidden;
  padding: 12px;
  background: #F0F2F4;
  position: relative;
  /* No max-width — always fills the available width of .at-chart-zone
     (the whole laptop/device screen, minus topbar/bottom-bar). Previously
     capped at 640px unzoomed with a class-toggled expansion to (near-)
     unbounded once zoom crossed 1.0 (issue #28), animated with a CSS
     transition (issue #30) — removed entirely, not just re-tuned: with
     nothing about the pane's own size ever changing, there's nothing left
     to jump no matter how zoom/pan behaves inside it, and per live
     feedback the pane wasn't making good use of a laptop screen even
     unzoomed. */
}

/* Zoom/pan is a pure transform (translate+scale) driven by pan_x/pan_y/zoom
   signals in active_tracking.rs — the same architecture the PDF picker's
   crop/setup overlays use (see .pp-crop-canvas). Superseded the earlier
   width:{zoom}% + flex-shrink:0 + native-scroll approach entirely (issue
   #26's flex-shrink fix and #30's zoom-jump chase both applied to that old
   approach — moot now that it's gone). transform-origin:0 0 matches the
   pan math's assumption that translate offsets from the top-left; no
   transition is needed or wanted here — unlike a width change, transform
   is compositor-only, so the browser already interpolates smoothly between
   any two rapid updates with zero jank, and adding a CSS transition on top
   would only fight fast-changing drag/pinch gestures. */
.at-chart-zoom-inner {
  width: 100%;
  position: relative;
  transform-origin: 0 0;
  touch-action: none;
  will-change: transform;
}

.at-chart-img-wrap {
  display: block;
  position: relative;
  line-height: 0;
  width: 100%;
}

.at-chart-img {
  display: block;
  width: 100%;
  height: auto;
  background: white;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}

/* No border-top/border-bottom — removed per the highlight-bar-enhancements
   map's settled ground rule (unconditional, not a toggle). Opacity is set
   inline per-piece by highlight_style() (active_tracking.rs); the
   background here is only the pre-highlight_color fallback. */
.at-row-highlight {
  position: absolute;
  left: 0;
  right: 0;
  background: rgba(99, 102, 241, 0.15);
  pointer-events: none;
}

/* Text piece row highlight — top-anchored (boundaries go top→bottom) */
.at-text-row-highlight {
  position: absolute;
  left: 0;
  right: 0;
  background: rgba(139, 92, 246, 0.25);
  pointer-events: none;
}

.at-chart-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}

/* Shown over the full-page image when grid boundary not yet marked */
.at-chart-placeholder-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.45);
  border-radius: var(--radius-md);
}

.at-placeholder-text {
  font-size: var(--fs-12);
  color: var(--ink-light);
  font-style: italic;
}

/* ── Bottom bar ── */
.at-bottom-bar {
  background: var(--surface);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 4px 12px;
  gap: 8px;
  min-height: 40px;
  flex-shrink: 0;
}

.at-instr-content {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Row instructions — fixed, always-reserved height (scrolls internally if
   more badges fire than fit) so steps starting/stopping never shifts the
   RS/WS pill, Rep pill, or session label. See specs/pages/active-tracking.md
   § Row instructions. */
.at-row-instr-row {
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
  max-height: 40px;
  overflow-y: auto;
  display: flex;
  align-items: center;
  gap: 4px 8px;
}

/* Only applied while the active chart has at least one row instruction —
   min-height matches max-height so this is a truly fixed reserved height
   (not just a cap), immune to being squeezed by long badge text wrapping. */
.at-row-instr-row-reserved {
  min-height: 40px;
}

.at-row-instr-step {
  font-size: var(--fs-14);
  color: var(--ink);
  white-space: normal;
  overflow-wrap: break-word;
}

.at-side-pill {
  font-size: var(--fs-12);
  font-weight: 700;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
  flex-shrink: 0;
  font-family: var(--font-sans);
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums lining-nums;
}

.at-session-label {
  font-size: var(--fs-9);
  color: var(--ink-light);
  white-space: nowrap;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums lining-nums;
}

/* Row-instruction completion banner — transient, 2500ms auto-dismiss. See
   specs/pages/active-tracking.md § Row instructions, "Completion banner". */
.at-completion-banner {
  position: fixed;
  bottom: 56px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--bg);
  font-size: var(--fs-12);
  font-weight: 600;
  padding: 6px 14px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  z-index: 95;
  white-space: nowrap;
}

/* ── Formatting menu — the trigger is now a plain .at-tb-icon (same footprint
   as Reference/More-options), not its own bespoke button style. Design
   feedback: "move the formatting config on this menu bar somewhere else,
   into a menu" — consolidates what used to be two always-visible controls
   (a color swatch, .at-tb-color-wrap below, and a "{opacity}%" text button,
   .at-tb-opacity-btn below — both since removed, dead) into one icon behind
   a popover. That consolidation is also why the small-screen hide rule that
   used to live here (hiding both controls below 480px so the row-function
   cluster stayed reachable) is gone too — one small icon doesn't crowd the
   bar the way two separate controls did, so nothing needs hiding anymore. ── */
.at-tb-opacity-wrap {
  position: relative;
  flex-shrink: 0;
}

/* Color row inside the formatting popover — label + the ColorPicker swatch,
   moved in here from its own former standalone topbar control. Swatch
   shrunk the same way it was there (.cp-swatch's default 26px reads heavy
   next to this popover's other compact controls), scoped to this wrapper
   only, not a change to color-picker.css's shared default. */
.at-format-color-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.at-format-label {
  font-size: var(--fs-12);
  color: var(--ink-mid);
  font-family: var(--font-sans);
}
.at-format-color-row .cp-swatch {
  width: 20px;
  height: 20px;
}

/* position:fixed, not absolute — .at-topbar's overflow-x:auto (issue #42)
   forces its overflow-y to compute as `auto` too (CSS Overflow spec: one
   axis can't stay `visible` once the other isn't), which silently clipped
   this when it was positioned relative to .at-tb-opacity-wrap inside the
   topbar — the button still worked, the popover just never became visible.
   top/right now come from the trigger button's own bounding rect (inline
   style, set in active_tracking.rs's menu_pos_below) instead of this rule's
   own top/right, matching how the counter tooltip is already positioned. */
.at-opacity-popover {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  z-index: 200;
  padding: 10px 12px;
}

.at-opacity-slider {
  width: 120px;
  accent-color: var(--accent);
  display: block;
}

/* ── Invert-mode toggle, inside the opacity popover ── */
.at-invert-toggle-row {
  display: flex;
  gap: 4px;
  margin-top: 8px;
}

.at-invert-toggle-btn {
  flex: 1;
  height: 24px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface2);
  color: var(--ink-mid);
  font-family: var(--font-sans);
  font-size: var(--fs-10);
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}
.at-invert-toggle-active {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

/* ── More-options menu (Reset to row 1 / Go to specific row). Trigger now
   lives inside .at-row-overlay (below), not a topbar wrapper — the menu
   itself is unchanged, still a position:fixed portal computed from the
   trigger button's live getBoundingClientRect(). ── */
/* position:fixed — same reason as .at-opacity-popover above: clipped by
   .at-topbar's overflow-x:auto forcing overflow-y to `auto` too when this
   was positioned relative to a wrapper inside the topbar. The menu
   opened (the signal flipped) but was never actually visible. */
.at-back-menu {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  z-index: 200;
  min-width: 190px;
}

.at-back-menu-item {
  display: block;
  width: 100%;
  height: 38px;
  padding: 0 14px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: background 0.15s;
}
.at-back-menu-item:last-child { border-bottom: none; }
.at-back-menu-item:hover:not(:disabled) { background: var(--surface2); }
.at-back-menu-item:disabled { opacity: 0.38; cursor: not-allowed; }

.at-back-menu-dim { color: var(--ink-mid); }

/* ── Floating row-controls overlay (wayfinder rowbie#65/#68) ──
   position:fixed portal, same pattern as counter_tooltip/.at-back-menu/
   .at-opacity-popover above — left/top driven entirely by inline style
   from overlay_x/overlay_y (JS-measured against the chart viewport, see
   apply_overlay_position() in active_tracking.rs), not by CSS. Contains
   the drag handle plus the −/+/More-options/rotate action buttons that
   used to live in .at-topbar — moved out per design feedback so they can
   be dragged to wherever the user's thumb naturally rests, independent
   of the topbar's fixed layout. Default shape is vertical (a column);
   the rotate button toggles .at-row-overlay-vertical off for a horizontal
   row instead — a manual override of the cluster's own orientation, not
   a chart-rotation feature. Position AND orientation are remembered per
   screen-size bucket in localStorage only (rb_at_overlay_pos) — this is
   a per-device UI habit, not project data, so it's never synced to the
   server or stored on Project/ProjectChart/TextPiece. */
.at-row-overlay {
  position: fixed;
  z-index: 150;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  padding: 6px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  touch-action: none;
}
.at-row-overlay-vertical { flex-direction: column; }
.at-row-overlay-dragging {
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
  opacity: 0.92;
}

.at-row-overlay-handle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  color: var(--ink-light);
  letter-spacing: 2px;
  font-size: var(--fs-14);
  cursor: grab;
  flex-shrink: 0;
  user-select: none;
  touch-action: none;
}
.at-row-overlay-dragging .at-row-overlay-handle { cursor: grabbing; }

.at-row-overlay-btn {
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-mid);
  font-size: var(--fs-14);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s, opacity 0.15s;
}
.at-row-overlay-btn:hover:not(:disabled) { background: var(--accent-lt); color: var(--accent); border-color: var(--accent); }
.at-row-overlay-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* − / + get the same solid-fill treatment as .btn-primary — they're the
   controls actually pressed over and over, so they stay visually louder
   than More-options/rotate even though all four share one cluster now. */
.at-row-overlay-btn-primary {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
  font-weight: 600;
}
.at-row-overlay-btn-primary:hover:not(:disabled) { background: var(--accent); color: var(--bg); opacity: 0.88; }

/* − gets its own color, not the shared teal .at-row-overlay-btn-primary —
   design feedback: "too easy to hit the minus by accident... can we use a
   different color." color:#fff (not var(--bg)) matches the existing
   danger-button precedent (.at-confirm-ok) rather than CLAUDE.md's
   accent-button color rule, which is specific to var(--accent). */
.at-row-overlay-btn-danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
  font-weight: 600;
}
.at-row-overlay-btn-danger:hover:not(:disabled) { background: var(--danger); color: #fff; opacity: 0.88; }

/* ── Reset confirm overlay ── */
.at-overlay {
  background: rgba(0,0,0,0.55);
  z-index: 300;
  align-items: center;
  justify-content: center;
}

.at-confirm-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  padding: 20px;
  width: 300px;
  max-width: calc(100vw - 40px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow);
}

.at-confirm-title {
  font-size: var(--fs-16);
  font-weight: 600;
  color: var(--ink);
}

.at-confirm-sub {
  font-size: var(--fs-12);
  color: var(--ink-mid);
  line-height: 1.5;
  margin-top: -4px;
}

.at-confirm-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

.at-confirm-cancel {
  flex: 1;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-mid);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  cursor: pointer;
  transition: all 0.12s;
}
.at-confirm-cancel:hover { border-color: var(--ink-mid); color: var(--ink); }

.at-confirm-ok {
  flex: 1;
  height: 36px;
  border: none;
  border-radius: var(--radius-md);
  background: var(--danger);
  color: #fff;
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s;
}
.at-confirm-ok:hover { opacity: 0.88; }

/* ── Jump-to-row modal ── */
.at-jump-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  padding: 20px;
  width: 340px;
  max-width: calc(100vw - 40px);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow);
  position: relative;
  overflow: hidden;
}

.at-jump-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  color: var(--ink-light);
  font-size: var(--fs-16);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  transition: all 0.12s;
}
.at-jump-close:hover { background: var(--surface2); color: var(--ink); }

.at-jump-title {
  font-size: var(--fs-16);
  font-weight: 600;
  color: var(--ink);
  padding-right: 28px;
}


.at-jump-input-wrap {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.at-jump-feedback {
  min-height: 18px;
  font-size: var(--fs-12);
  font-weight: 600;
  color: var(--accent);
  text-align: center;
}

.at-jump-input {
  height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-24);
  font-weight: 400;
  text-align: center;
  outline: none;
  width: 100%;
  transition: border-color 0.15s;
  box-sizing: border-box;
}
.at-jump-input:focus { border-color: var(--accent); }
.at-jump-input::placeholder { color: var(--ink-light); font-size: var(--fs-14); }

.at-jump-actions {
  display: flex;
  gap: 8px;
}

.at-jump-cancel {
  flex: 1;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-mid);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  cursor: pointer;
  transition: all 0.12s;
}
.at-jump-cancel:hover { border-color: var(--ink-mid); color: var(--ink); }

.at-jump-confirm {
  flex: 1;
  height: 36px;
  border: none;
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--bg);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s;
}
.at-jump-confirm:hover:not(:disabled) { opacity: 0.88; }
.at-jump-confirm:disabled { opacity: 0.35; cursor: not-allowed; }

/* ── Quick Reference ? button ── */
.at-tb-icon {
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-mid);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  flex-shrink: 0;
}
.at-tb-icon:hover { background: var(--accent-lt); color: var(--accent); border-color: var(--accent); }
.at-tb-icon-active { background: var(--accent); color: var(--bg); border-color: var(--accent); }

/* ── Quick Reference slide panel ── */
.at-ref-panel {
  position: fixed;
  top: 44px;
  right: 0;
  bottom: 48px;
  width: 272px;
  background: var(--surface);
  border-left: 1px solid var(--border);
  z-index: 90;
  transform: translateX(110%);
  transition: transform 0.22s ease;
  overflow-y: auto;
  padding: 16px;
  box-shadow: var(--shadow);
}
.at-ref-panel-open { transform: translateX(0); }

.at-ref-title {
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-light);
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.at-ref-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
}

.at-ref-tab {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  font-weight: 500;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: transparent;
  color: var(--ink-mid);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.at-ref-tab:hover { border-color: var(--ok); color: var(--ok); }
.at-ref-tab-active { background: var(--ok); border-color: var(--ok); color: var(--bg); font-weight: 600; }

.at-ref-img-btn {
  display: block;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: left;
}
.at-ref-img {
  width: 100%;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  display: block;
}
.at-ref-hint {
  display: block;
  font-size: var(--fs-10);
  color: var(--ink-mid);
  text-align: center;
  padding: 4px 0 0;
  font-style: italic;
}
.at-ref-empty {
  font-size: var(--fs-12);
  color: var(--ink-mid);
  text-align: center;
  padding: 16px 0;
  font-style: italic;
}

/* ── Quick Reference lightbox ── */
.at-lightbox {
  z-index: 9999;
  background: rgba(0, 0, 0, 0.93);
  flex-direction: column;
  align-items: stretch;
}
.at-lightbox-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  font-size: var(--fs-18);
  cursor: pointer;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.at-lightbox-close:hover { background: rgba(255, 255, 255, 0.3); }
.at-lightbox-img-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  touch-action: none;
}
.at-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  transform-origin: center;
  user-select: none;
  pointer-events: none;
}
.at-lightbox-hint {
  padding: 10px;
  text-align: center;
  font-size: var(--fs-12);
  color: rgba(255, 255, 255, 0.4);
  flex-shrink: 0;
}
