/* Goal Tracking: player-built targets (boss KC, skill level/xp, item quantity)
   with live progress (render_goal_tracking in app/pages/). Add-goal wizard on
   top, goal list below. */

.gt-card {
  background: var(--panel-translucent);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 24px;
  margin-bottom: 20px;
}

.gt-link-note { color: var(--text-muted); margin: 0; }

/* Add-goal wizard. Collapsed (.gt-wizard-add-btn alone) or expanded
   (.gt-wizard-expanded, a multi-stage flow; see
   wizardStage1Html/wizardStage2Html in the script); only one is visible at a
   time (renderWizard). */

.gt-wizard {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.gt-wizard-add-btn {
  background: var(--gold);
  color: #221c10;
  border: none;
  border-radius: var(--radius);
  font-family: inherit;
  height: 25px;
  padding: 0 28px;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-wizard-add-btn:hover { background: #ffab42; }

/* Fixed size across every stage so the box never jumps between stages; stage
   content fills it, with the top row flush to the top and the actions row pinned
   to the bottom via margin-top: auto. 160px fits the tallest stage with slack
   (34px field row + 25px segmented row + 25px actions row + two 11px gaps =
   106px, inside 160 minus the 26/20 vertical padding = 114px). max-width 380px:
   the widest row is Back/Cancel/Next, 3 buttons at 316px (100px each + 8px
   gaps), inside 340px of content width (380 minus 20+20 padding). */
.gt-wizard-expanded {
  position: relative;
  width: 100%;
  max-width: 380px;
  height: 160px;
  background: var(--panel-translucent);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 20px 20px;
  display: flex;
  flex-direction: column;
}

#gtWizardStage { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }

/* Stage 1: type picker (three options) using the same icon assets as Mindmaps'
   GOAL_TYPE_PICKER (app/pages/), plus a centered Cancel. The wrap fills the
   fixed height like .gt-wizard-stage2: type cards at the top, Cancel pinned to
   the bottom by .gt-wizard-stage1-actions' margin-top: auto. */
.gt-wizard-stage1-wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  /* Flex items default to min-height: auto, which floors them at content size;
     same fix as #gtWizardStage. */
  min-height: 0;
}

/* Cards are fixed-size and no longer stretch, so center them under the centered
   actions row. */
.gt-wizard-stage1 {
  display: flex;
  justify-content: center;
  gap: 12px;
}

/* Cancel alone (stage 1) or Back + Cancel (stage 2), centered as a group. */
.gt-wizard-stage1-actions {
  display: flex;
  gap: 8px;
  align-self: center;
  /* margin-top: auto pins the row to the box bottom (as .gt-wizard-actions does
     for stages 3/4) without hand-computed leftover math. */
  margin-top: auto;
}

/* Fixed width and height (not just flex-basis) guarantee a 64x64 square;
   border-box (myscape.css * rule) keeps padding inside it. overflow: hidden
   guards the longest label ("SKILL LVL/XP") wrapping to a 3rd line (2 lines
   fit). flex: 0 1 64px lets cards shrink on narrow viewports (see the max-width:
   720px query). */
.gt-wizard-type-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  flex: 0 1 64px;
  width: 64px;
  height: 64px;
  overflow: hidden;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-family: inherit;
  padding: 6px 4px;
  cursor: pointer;
}

/* Sized to read as an icon without crowding the label in the 64px card. */
.gt-wizard-type-btn img { width: 22px; height: 22px; object-fit: contain; image-rendering: pixelated; }

/* Inline SVGs (ONE_TIME_ICON_SVG/RECURRING_ICON_SVG in the script) colored via
   currentColor; always gold, unlike the card's border/text which turn gold only
   on :hover. */
.gt-wizard-type-btn svg.gt-recur-icon { width: 22px; height: 22px; color: var(--gold); flex: none; }

/* Small font for two- and three-word labels ("Item Qty", "Skill Lvl/Xp") to fit
   2 lines in ~52px of content width (64 minus 4+4 padding and the 2px border).
   text-align: center centers each wrapped line; align-items: center only centers
   the block. */
.gt-wizard-type-btn span {
  font-size: 9px;
  line-height: 1.25;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: center;
}

.gt-wizard-type-btn:hover { border-color: var(--gold); color: var(--text); background: var(--panel); }

/* Stage 2: target search + value on top, segmented controls on their own row
   (.gt-wizard-segrow), then the actions row. gap sets the minimum spacing
   between present rows; .gt-wizard-actions' margin-top: auto pins the actions to
   the box bottom. */
.gt-wizard-stage2 {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  gap: 11px;
}

.gt-wizard-row { display: flex; gap: 12px; align-items: center; }

/* Placeholder text on the input replaces a label
   (WIZARD_SEARCH_PLACEHOLDER/wizardTargetPlaceholder in the script).
   flex-direction: column makes the single child stretch to full width via the
   default align-items: stretch. */
.gt-field { display: flex; flex-direction: column; flex: 1 1 200px; min-width: 160px; }

.gt-field select, .gt-field input[type="number"], .gt-field input[type="text"] { width: 100%; height: 34px; padding: 0 12px; }

/* The search field grows to fill what the fixed-width target field leaves,
   keeping each goal type's fields on one line regardless of name length. */
.gt-wizard-row .gt-field-target-search { flex: 1 1 auto; min-width: 0; }
.gt-wizard-row .gt-field-target { flex: 0 0 118px; min-width: 0; }

/* Row for stage 3's Lvl/Xp toggle and/or GAIN/REACH field
   (#gtWizardSegRow/#gtTargetModeField in wizardStageTargetHtml, app/pages/),
   centered as a group. --empty (toggled by updateWizardSegRowVisibility in the
   script) collapses it for item goals and skill goals on Lvl, which have no
   segmented control. */
.gt-wizard-segrow { display: flex; gap: 10px; justify-content: center; align-items: center; }
.gt-wizard-segrow--empty { display: none; }

/* :empty rather than width: 0: a display: none field is skipped by flexbox, so
   it takes no space or gap. Whether the whole row disappears is handled by
   .gt-wizard-segrow--empty above. */
#gtTargetModeField:empty { display: none; }

/* A missing/out-of-range field shows a red border only
   (validateTargetField/validateRecurField and the search-input .invalid toggles
   in the script). The rule lives at the end of this file so it wins on source
   order. */

/* Back/Cancel use the same secondary look as .btn-secondary in
   mindmaps.css/purchase-goals.css (duplicated per page stylesheet). All buttons,
   Save/Next (.gt-add-btn) included, share a fixed 100px width. align-self:
   center centers narrower rows (e.g. Cancel alone); margin-top: auto pins the
   row to the box bottom so every stage's actions land on the same edge. */
.gt-wizard-actions { display: flex; gap: 8px; align-self: center; margin-top: auto; }

/* 25px is the site-wide button height (from .loot-sort-tab in loot-tracker.css).
   display: flex with centering keeps the label centered at that height
   regardless of font-size/padding. */
.gt-wizard-btn {
  flex: 0 0 auto;
  width: 100px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-family: inherit;
  height: 25px;
  padding: 0 14px;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-wizard-btn:hover { border-color: var(--gold-dim); color: var(--text); }

.gt-wizard-actions .gt-add-btn { flex: 0 0 auto; width: 100px; height: 25px; }

/* Next (stage 3, recurring only; wizardStageTargetHtml) uses the plain
   Back/Cancel look instead of gold, so it does not read as the button that
   creates the goal (Save is on stage 4). */
.gt-wizard-actions .gt-add-btn.gt-wizard-btn-next {
  background: var(--panel-2);
  color: var(--text-dim);
  border: 1px solid var(--border);
}

.gt-wizard-actions .gt-add-btn.gt-wizard-btn-next:hover {
  background: var(--panel-2);
  border-color: var(--gold-dim);
  color: var(--text);
}

/* Level/XP toggle inside #gtWizardSegRow (wizardStageTargetHtml, app/pages/);
   explicit 108px width (2 x 54px segments) since no flex sibling sizes it. 25px
   site-wide button height. */
.gt-metric-toggle { display: flex; gap: 0; height: 25px; width: 108px; flex: none; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }

.gt-metric-btn {
  flex: 1 1 50%;
  height: 100%;
  background: #100e0b;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 1px divider between segments; the last has none (the toggle's border closes
   it). */
.gt-metric-btn:last-child { border-right: none; }

.gt-metric-btn:hover { color: var(--text); }

.gt-metric-btn.active { background: var(--panel-2); color: var(--gold); }

/* GAIN/REACH toggle (inside #gtTargetModeField in #gtWizardSegRow); same look as
   .gt-metric-toggle but its own class, as it is a separate choice. 128px width
   fits "REACH". */
.gt-target-mode-toggle { display: flex; gap: 0; height: 25px; width: 128px; flex: none; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }

.gt-target-mode-btn {
  flex: 1 1 50%;
  height: 100%;
  background: #100e0b;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-target-mode-btn:last-child { border-right: none; }

.gt-target-mode-btn:hover { color: var(--text); }

.gt-target-mode-btn.active { background: var(--panel-2); color: var(--gold); }

/* A one-time skill goal on LEVEL (targetModeVisible/wireTargetModeToggle in the
   script) shows this toggle dimmed and non-interactive (pointer-events: none)
   since GAIN/REACH has no meaning there; neither button is .active. Switching to
   XP re-wires it with GAIN selected. */
.gt-target-mode-toggle--disabled { opacity: 0.4; pointer-events: none; }

/* Stage 4 (recurring only): the interval field, centered via justify-content;
   the unit toggle is on its own .gt-wizard-segrow row. */
.gt-wizard-recur-fields { display: flex; flex-direction: row; justify-content: center; }

/* Narrow fixed-width count field. Selector is input.* because myscape.css's
   input[type="text"] (width: 100%, padding: 12px 14px) is type + attribute and
   beats a lone class on specificity regardless of source order. */
input.gt-recur-interval-input { width: 140px; flex: 0 0 auto; height: 34px; padding: 0 12px; }

/* Segmented toggle generalized to 5 buttons: borders overlap with a uniform -1px
   margin-left and the active/hovered button is lifted with z-index so its full
   border shows. 25px site-wide button height. Segments are a fixed 54px (5*54 -
   4*1px overlap = 266px), matching .gt-metric-toggle's per-segment width;
   .gt-wizard-segrow's justify-content: center centers it
   (wizardStageCadenceHtml, app/pages/). */
.gt-recur-unit-toggle { display: flex; height: 25px; flex: none; width: 266px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }

.gt-recur-unit-btn {
  flex: 1 1 0;
  height: 100%;
  background: #100e0b;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-recur-unit-btn:last-child { border-right: none; }

.gt-recur-unit-btn:hover { color: var(--text); }

.gt-recur-unit-btn.active { background: var(--panel-2); color: var(--gold); }

/* Stage 5 (recurring only): when the cadence starts. Reuses the stage 4 layout
   with a masked date/time field and a NOW/CUSTOM toggle. 160px fits the full
   "YYYY-MM-DD HH:MM" mask (~100px of text at the inherited 16px input font size,
   see input[type="text"] in myscape.css) with padding. */
input.gt-recur-start-input { width: 160px; flex: 0 0 auto; height: 34px; padding: 0 12px; }

/* Disabled (NOW picked; wireStartStage in the script) is dimmed like
   .gt-target-mode-toggle--disabled, via :disabled since a disabled input already
   gets the native behavior. */
input.gt-recur-start-input:disabled { opacity: 0.4; }

/* Same look as .gt-target-mode-toggle. 140px (70px per segment): "CUSTOM" is
   longer than "REACH". */
.gt-recur-start-toggle { display: flex; gap: 0; height: 25px; width: 140px; flex: none; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }

.gt-recur-start-btn {
  flex: 1 1 50%;
  height: 100%;
  background: #100e0b;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-recur-start-btn:last-child { border-right: none; }

.gt-recur-start-btn:hover { color: var(--text); }

.gt-recur-start-btn.active { background: var(--panel-2); color: var(--gold); }

.gt-field-target-search { position: relative; }

.gt-search-box { position: relative; }

.gt-search-box input[type="text"] { width: 100%; height: 34px; padding: 0 12px; }

/* Same look as .suggestions/.suggestion in purchase-goals.css (local copy per
   page stylesheet). */
.gt-suggestions {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 6;
  background: var(--panel);
  border: 1px solid var(--border);
  max-height: 240px;
  overflow-y: auto;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
  /* Stops scroll chaining into the page past the list bounds (same as
     .mm-suggestions and .pm-settings-menu). */
  overscroll-behavior: contain;
}

.gt-suggestions.show { display: block; }

.gt-suggestion {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
}

.gt-suggestion:hover { background: var(--panel-2); }

.gt-suggestion img {
  width: 24px;
  height: 24px;
  object-fit: contain;
  image-rendering: pixelated;
}

.gt-add-btn {
  background: var(--gold);
  color: #221c10;
  border: none;
  border-radius: var(--radius);
  font-family: inherit;
  height: 25px;
  padding: 0 20px;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gt-add-btn:hover { background: #ffab42; }

/* Goal list */

/* Sort tabs: same look as .loot-sort-tabs/.loot-sort-tab (loot-tracker.css),
   local copy. Equal-width buttons, one active at a time (updateSortTabs in the
   script). Hidden when the list is (renderGoalList). */
/* 5 buttons: Progress/Type/A-Z/Time each toggle their direction in place via the
   .gt-sort-arrow span, plus Custom. 25px box model shared with .loot-sort-tab
   and .sort-btn. */
.gt-sort-tabs { display: flex; gap: 5px; margin-bottom: 14px; }

.gt-sort-tab {
  flex: 1;
  height: 25px;
  display: flex; align-items: center; justify-content: center;
  padding: 0 3px;
  font-size: 10px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  text-align: center;
}

.gt-sort-tab:hover { border-color: var(--gold-dim); color: var(--text); }
.gt-sort-tab.active { border-color: var(--gold); color: var(--gold); }
/* Nudge for the fallback-font arrow glyph (RuneScapePlain11 has no arrows); see
   .loot-sort-arrow in loot-tracker.css. */
.gt-sort-arrow { position: relative; top: -1px; }

/* One-off nudge pulse for CUSTOM when a goal row is clicked/dragged in another
   sort mode (glowCustomSortTab in the script); same shape as
   sort-btn-custom-glow in purchase-goals.css. */
@keyframes gt-sort-tab-custom-glow {
  0%, 100% { box-shadow: none; border-color: var(--border); color: var(--text-dim); }
  50% { box-shadow: 0 0 8px 2px var(--gold); border-color: var(--gold); color: var(--gold); }
}
.gt-sort-tab.glow { animation: gt-sort-tab-custom-glow 0.6s ease-in-out 2; }

.gt-empty { text-align: center; color: var(--text-faint); font-size: 13px; padding: 30px 10px; }

.gt-goal-list { display: flex; flex-direction: column; }

.gt-goal-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
  /* .gt-goal-delete is absolutely positioned so it overlays the row without
     claiming a flex track, leaving .gt-goal-info/.gt-goal-bar the full width. */
  position: relative;
}

.gt-goal-list .gt-goal-row:last-child { border-bottom: none; }

/* Drag-to-reorder, custom sort mode only (wireGoalDrag in the script); same as
   .gear-summary-row.draggable/.dragging in purchase-goals.css: rows slide aside
   (animateReorder) instead of a drop ring, user-select: none avoids text
   selection. */
.gt-goal-row.draggable { cursor: grab; user-select: none; }
.gt-goal-row.draggable:hover { background-color: rgb(51, 51, 54); }
.gt-goal-row.draggable.dragging { opacity: 0.4; cursor: grabbing; }

.gt-goal-icon {
  width: 30px;
  height: 30px;
  object-fit: contain;
  image-rendering: pixelated;
  flex: 0 0 auto;
}

.gt-goal-info { flex: 1 1 auto; min-width: 0; }

/* Name and progress text share a line; align-items: baseline aligns the
   differently-sized texts. padding-right reserves room for the overlaid
   .gt-goal-delete at its widest ("Are you sure?"); the bar below does not need
   it. */
.gt-goal-headline {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding-right: 92px;
}

.gt-goal-name {
  color: var(--text);
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* flex-grow: 0 keeps the progress text right after the name. The name shrinks
     first (not .gt-goal-sub): an ellipsized name reads fine, a truncated
     progress readout does not. */
  flex: 0 1 auto;
  /* Ceiling for how far fixGoalNameMinWidths (script) narrows the name per row,
     and the protection against a long .gt-goal-sub squeezing the name to
     nothing. A flat min-width would pad short titles out to 48px (a flex item
     clamps up to min-width), making the gap after each title uneven. Keep in
     sync with GT_GOAL_NAME_MIN_WIDTH in the script. */
  min-width: 48px;
}

.gt-goal-sub {
  color: var(--text-faint);
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  /* Never shrinks or wraps (the name gives way first) and takes only the width
     its text needs. */
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Doubles as the progress readout (goalProgressLabel in the script), so it takes
   the done-state green. */
.gt-goal-done .gt-goal-sub { color: var(--green); }

/* Hover-only "i" after a recurring goal's cadence tag (recurInfoIconHtml in the
   script); the native title attribute is the tooltip. Inline-flex centers it on
   the cadence text's line. */
.gt-goal-info-icon {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 3px;
  color: var(--text-faint);
}
.gt-goal-info-icon:hover { color: var(--gold); }

.gt-goal-bar {
  width: 100%;
  height: 9px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  margin-top: 6px;
}

.gt-goal-bar-fill { height: 100%; background: var(--gold); }

/* Completed goals (current_value reaches target_value; .gt-goal-done set in
   goalRowHtml) show green. */
.gt-goal-done .gt-goal-bar-fill { background: var(--green); }

.gt-goal-delete {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--text-faint);
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Overlaid on the row's top-right corner so it never claims width from
     .gt-goal-info. See .gt-goal-row's position: relative and .gt-goal-name's
     padding-right. */
  position: absolute;
  top: 10px;
  right: 4px;
}

.gt-goal-delete:hover { color: var(--red); }

.gt-goal-delete-icon { display: block; }

/* Hidden until the button is armed (delegated click handler in the script); the
   same element swaps from trash icon to confirm label. */
.gt-goal-delete-confirm {
  display: none;
  font-size: 10px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
}

.gt-goal-delete--confirm {
  color: var(--red);
  border-color: var(--red);
  padding: 4px 10px;
}

.gt-goal-delete--confirm .gt-goal-delete-icon { display: none; }
.gt-goal-delete--confirm .gt-goal-delete-confirm { display: block; }

/* Shared invalid-field rule for #gtWizardSearchInput, #gtTargetValue,
   #gtRecurInterval and #gtRecurStartInput. Placed last so it wins specificity
   ties (0,2,1) on source order, and beats the (0,1,1) selectors outright. */
input[type="text"].invalid { border-color: var(--red); }

@media (max-width: 720px) {
  /* Fields stay in a row on narrow screens, with tighter fixed widths instead of
     stacking. */
  .gt-wizard-row .gt-field-target { flex-basis: 96px; }
  .gt-metric-toggle { width: 92px; }
  .gt-target-mode-toggle { width: 108px; }
}

/* Landing-page interactive preview (render_landing_goal_tracking_preview):
   container/feather, then the hero row. Scoped under
   .landing-goal-tracking-preview so none of it reaches the real page. Mirrors
   .landing-loot-preview/.loot-preview-hero in loot-tracker.css, except the DOM
   order puts the tagline first and the character on the right. */

.landing-goal-tracking-preview {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  /* Fixed height (not max-height) so the bottom feather stays at the same screen
     position however much content is inside; see .landing-loot-preview in
     loot-tracker.css. */
  height: calc(100vh - 80px);
  height: calc(100svh - 80px);
  overflow: hidden;
  position: relative;
}
/* Unconditional; no --clipped modifier (see .landing-loot-preview::after in
   loot-tracker.css). */
.landing-goal-tracking-preview::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 15%;
  background: linear-gradient(to bottom, transparent, var(--bg));
  pointer-events: none;
}

/* Hide the reused body's heading rather than strip it from the markup
   (_goal_tracking_panel_markup stays untouched); the tagline replaces it. */
.landing-goal-tracking-preview .page-title { display: none; }

/* Hide the reused "Add goal" wizard (#gtWizard) without stripping it, so the
   page script's getElementById('gtWizardAddBtn') listener still finds its
   element. Creating goals fails in this demo (POST /api/goals shim). display:
   none (not visibility) collapses the shared .gt-wizard margin-bottom so the
   list card sits flush under the hero row. */
.landing-goal-tracking-preview #gtWizard { display: none; }

/* The delete button stays visible and hoverable (same red hover tint as the real
   page); actual deletion is blocked by a capture-phase click interceptor on
   #gtGoalList in render_landing_goal_tracking_preview's script. pointer-events:
   none would also suppress the hover, so only cursor: default is set. */
.landing-goal-tracking-preview .gt-goal-delete { cursor: default; }

/* Tagline wrap first in source order, character second: the mirror of
   .loot-preview-hero, so the character lands on the right with no
   flex-direction/order override. align-items: flex-end bottom-aligns the
   character on the goal list's top border. */
.gt-preview-hero {
  display: flex;
  align-items: flex-end;
}
.gt-preview-tagline-wrap {
  flex: 1 1 auto;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}
.gt-preview-tagline {
  margin: 0;
  max-width: 100%;
  min-width: 0;
  text-align: center;
  font-size: 30px;
  line-height: 1.25;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gt-preview-tagline-gold { color: var(--gold); }
.gt-preview-tagline-white { color: var(--text); }

/* 157px standardized preview character height (see .loot-preview-char in
   loot-tracker.css); the source image is 425x410, cropped to its upper half. */
.gt-preview-char {
  flex: 0 0 auto;
  height: 157px;
  line-height: 0;
}
.landing-goal-tracking-preview .gt-preview-char img {
  display: block;
  height: 100%;
  max-height: none;
  width: auto;
  max-width: none;
}
/* Mirrored horizontally (as .loot-preview-char--flipped in loot-tracker.css) so
   the character faces the tagline. */
.landing-goal-tracking-preview .gt-preview-char--flipped img {
  transform: scaleX(-1);
}


/* Share icon (export button next to "Goal Tracking"): same
   bare-icon/floating-popup recipe as
   .loot-share-wrap/.pg-share-wrap/.pm-share-wrap/.mm-share-wrap, duplicated per
   page. The 32px top and centering-via-transform come from the measured fix in
   .loot-share-wrap/.loot-share-card (loot-tracker.css); the page title shares
   the same 22px/1.5 font-size. */
.gt-share-wrap {
  position: relative; display: inline-block; vertical-align: middle; margin-left: 8px;
}
.gt-share-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  line-height: 1;
  color: var(--text-faint);
  transition: color 0.15s ease;
  position: relative;
  top: -2px;
}
.gt-share-icon-btn:hover { color: var(--text-dim); }
.gt-share-icon-btn.open { color: var(--gold); }
.gt-share-card {
  position: absolute; top: 32px; left: 50%; transform: translateX(-50%); z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 280px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 5px 6px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}
/* Author display outranks the browser's [hidden] rule (same as
   .loot-share-card[hidden] in loot-tracker.css). */
.gt-share-card[hidden] { display: none; }
.gt-share-generate-btn {
  height: 28px;
  padding: 0 10px;
  font-size: 15px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
}
.gt-share-generate-btn:hover { border-color: var(--gold-dim); color: var(--text); }
.gt-share-generate-btn:disabled { cursor: default; opacity: 0.6; }
.gt-share-generate-btn.action-failed { border-color: var(--red); color: var(--red); }
.gt-share-link-btn {
  height: 28px;
  padding: 0 10px;
  font-size: 15px;
  font-family: inherit;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gt-share-link-btn:hover { border-color: var(--gold-dim); color: var(--text); }
.gt-share-popup-hint { margin: 0; font-size: 13px; color: var(--text-faint); text-align: center; }

/* Save-to-your-account icon (import_icon_btn in render_goal_tracking_share,
   app/pages/); same recipe as the other pages' .*-import-wrap/.*-import-card,
   duplicated per page. */
.gt-import-wrap { position: relative; display: inline-block; vertical-align: middle; margin-left: 8px; }
.gt-import-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 0; margin: 0;
  cursor: pointer; line-height: 1;
  color: var(--text-faint); transition: color 0.15s ease;
  position: relative;
  top: -2px;
}
.gt-import-icon-btn:hover { color: var(--text-dim); }
.gt-import-icon-btn.open { color: var(--gold); }
.gt-import-card {
  position: absolute; top: 32px; left: 50%; transform: translateX(-50%); z-index: 5;
  display: flex; flex-direction: column; gap: 6px; width: 280px;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 5px 6px; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}
.gt-import-card[hidden] { display: none; }
.gt-import-save-btn {
  height: 28px; padding: 0 10px;
  font-size: 15px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
}
.gt-import-save-btn:hover { border-color: var(--gold-dim); color: var(--text); }
.gt-import-save-btn:disabled { cursor: default; opacity: 0.6; }
.gt-import-save-btn.action-failed { border-color: var(--red); color: var(--red); }
.gt-import-popup-hint { margin: 0; font-size: 13px; color: var(--text-faint); text-align: center; }

/* Share-viewing page (/s/<code>; see render_goal_tracking_share in
   app/pages/). .goal-tracking-share wraps the body. */

/* "GOAL TRACKING SNAPSHOT: YYYY-MM-DD" line above "Shared by <name>", like
   .loot-share-range/.pg-share-label/.pm-share-asof/.mm-share-label. The string
   is already uppercase, so no text-transform. */
.gt-share-label { text-align: center; margin: 0 0 4px; }

/* Hide the add-goal button and wizard on the share page (not stripped from the
   markup); same selector as the #gtWizard hide in
   .landing-goal-tracking-preview. */
.goal-tracking-share .gt-wizard { display: none; }

/* Segmented-control look shared site-wide (standardized on the Storages viewer's .pm-segment-btn): near-black idle segments, the active one a --panel-2 fill with gold text, 1px dividers between segments inside one outer border. (.gt-metric-btn, .gt-target-mode-btn, .gt-recur-unit-btn and .gt-recur-start-btn above.) */


/* Phone: same 320px centered column as the other pages. Scoped with
   body:not(.phone-off) so the homepage preview is untouched. */
@media (max-width: 700px) {
  body:not(.phone-off) .gt-wizard-expanded { max-width: 320px; padding: 26px 14px 20px; }
  body:not(.phone-off) .gt-card { max-width: 320px; margin-left: auto; margin-right: auto; padding: 14px; }
  body:not(.phone-off) .gt-wizard-row .gt-field-target { flex-basis: 112px; }
  /* Every wizard button is a fixed 82px so three fit in the 320px column,
     instead of stretching to the row. */
  body:not(.phone-off) .gt-wizard-btn,
  body:not(.phone-off) .gt-wizard-actions .gt-add-btn { flex: 0 0 auto; width: 82px; min-width: 0; padding: 0 4px; }
  body:not(.phone-off) .gt-wizard-expanded input[type="text"]::placeholder { font-size: 12px; }

  /* Name on its own line (ellipsized), progress readout below; the one-line pair
     truncated long names. */
  body:not(.phone-off) .gt-goal-row { gap: 12px; padding: 12px 0; }
  body:not(.phone-off) .gt-goal-headline {
    flex-direction: column; align-items: flex-start; gap: 2px;
    padding-right: 0;
  }
  body:not(.phone-off) .gt-goal-name { max-width: 100%; padding-right: 34px; box-sizing: border-box; }
  body:not(.phone-off) .gt-goal-row:has(.gt-goal-delete--confirm) .gt-goal-name { padding-right: 96px; }
  body:not(.phone-off) .gt-goal-sub { white-space: normal; }
  body:not(.phone-off) .gt-goal-info-icon { padding: 7px; margin: -7px -7px -7px -4px; }
  body:not(.phone-off) .gt-goal-row.draggable { -webkit-touch-callout: none; -webkit-user-drag: none; }

  body:not(.phone-off) .gt-sort-tabs { gap: 4px; }
  body:not(.phone-off) .gt-sort-tab { height: 28px; padding: 0 2px; font-size: 9.5px; }

  /* The share popup anchors to the title row, not the small icon, so it cannot
     run off the screen edge. */
  body:not(.phone-off) h2.page-title { position: relative; }
  body:not(.phone-off) .gt-share-wrap { position: static; }
  body:not(.phone-off) .gt-share-card { top: 100%; margin-top: 6px; width: min(280px, calc(100vw - 32px)); }
}


/* Touch: no sticky hover. A tap leaves :hover stuck, so the button that lands
   under the finger on the next wizard step looks highlighted. Without hover,
   restore resting styles and add a brief :active press look. Not applied on the
   homepage preview. */
@media (hover: none) {
  body:not(.phone-off) .gt-wizard-add-btn:hover,
  body:not(.phone-off) .gt-add-btn:hover { background: var(--gold); }
  body:not(.phone-off) .gt-wizard-add-btn:active,
  body:not(.phone-off) .gt-add-btn:active { background: #ffab42; }
  body:not(.phone-off) .gt-wizard-type-btn:hover { border-color: var(--border); color: var(--text-muted); background: var(--panel-2); }
  body:not(.phone-off) .gt-wizard-type-btn:active { border-color: var(--gold); color: var(--text); background: var(--panel); }
  body:not(.phone-off) .gt-wizard-btn:hover { border-color: var(--border); color: var(--text-dim); }
  body:not(.phone-off) .gt-wizard-btn:active { border-color: var(--gold-dim); color: var(--text); }
  body:not(.phone-off) .gt-wizard-actions .gt-add-btn.gt-wizard-btn-next:hover { background: var(--panel-2); border-color: var(--border); color: var(--text-dim); }
  body:not(.phone-off) .gt-wizard-actions .gt-add-btn.gt-wizard-btn-next:active { border-color: var(--gold-dim); color: var(--text); }
  body:not(.phone-off) .gt-metric-btn:not(.active):hover,
  body:not(.phone-off) .gt-target-mode-btn:not(.active):hover,
  body:not(.phone-off) .gt-recur-unit-btn:not(.active):hover,
  body:not(.phone-off) .gt-recur-start-btn:not(.active):hover { color: var(--text-dim); }
  body:not(.phone-off) .gt-suggestion:hover { background: transparent; }
  body:not(.phone-off) .gt-suggestion:active { background: var(--panel-2); }
  body:not(.phone-off) .gt-sort-tab:not(.active):hover { border-color: var(--border); color: var(--text-dim); }
  body:not(.phone-off) .gt-goal-row.draggable:hover { background-color: transparent; }
  body:not(.phone-off) .gt-goal-info-icon:hover { color: var(--text-faint); }
  body:not(.phone-off) .gt-goal-delete:not(.gt-goal-delete--confirm):hover { color: var(--text-faint); }
  body:not(.phone-off) .gt-share-icon-btn:not(.open):hover { color: var(--text-faint); }
  body:not(.phone-off) .gt-share-generate-btn:hover,
  body:not(.phone-off) .gt-share-link-btn:hover { border-color: var(--border); color: var(--text-dim); }
}


/* Share page "save to my account" icon, phone: the popup is centered on its icon
   at the right end of the title and would overflow, so anchor it to the
   full-width title. The 14px icon gets a thumb-sized tap area (padding with
   equal negative margin keeps the title layout unchanged). */
@media (max-width: 700px) {
  body:not(.phone-off) .page-title:has(.gt-import-wrap) { position: relative; }
  body:not(.phone-off) .gt-import-wrap { position: static; }
  body:not(.phone-off) .gt-import-card { top: calc(100% + 6px); }
  body:not(.phone-off) .gt-import-icon-btn { padding: 10px; margin: -10px; }
}

