/* ============================================================================
   Tight Lines: app styles.
   Loads LAST:  app-kit.css -> graphite.css -> tightlines.css
   Graphite supplies the near-black canvas and the component vocabulary. This
   file sets the accent, and then the handful of recipes this app needs that no
   other app does: the two-axis rating, the honest blank, and the protected-
   animal notice.
   ============================================================================ */

:root {
  /* The accent is the app's icon colour: shoal water over sand. Cyan-leaning so
     it never reads as Home Life's emerald or the Chief of Staff's blue. */
  --kit-accent:       #22c9d6;
  --kit-accent-hover: #63dde6;
  --kit-accent-2:     #0d6f78;
  --kit-accent-soft:  rgba(34, 201, 214, .12);
  --kit-accent-line:  rgba(34, 201, 214, .34);

  /* Deliberate second colour: the honest blank. The research left real things
     unverified, and the spec ships those as VISIBLE blanks rather than filling
     them in. A blank has to look like a blank, not like an answer, so it gets a
     warm sand that reads as "we do not know" rather than as "warning". */
  --tl-blank:      #f0b978;
  --tl-blank-bg:   rgba(240, 185, 120, .11);
  --tl-blank-line: rgba(240, 185, 120, .38);

  /* Third colour, used sparingly: legally protected. Sturgeon, manatee, sea
     turtles, nesting birds, horseshoe crabs. This is a prohibition, not a goal
     state, so a red family is the right register here. */
  --tl-protect:      #ff8f9c;
  --tl-protect-bg:   rgba(255, 143, 156, .10);
  --tl-protect-line: rgba(255, 143, 156, .40);

  --tl-rule: rgba(255, 255, 255, .09);
}

.kit-content { padding-bottom: max(2.5rem, env(safe-area-inset-bottom)); }

/* --- the fixture banner ---------------------------------------------------
   Only ever rendered when the bundle was built from stand-in tables. It is
   loud on purpose: a render that could be mistaken for the real guide is the
   whole risk of building ahead of the data. */
.tl-fixture {
  background: var(--tl-protect-bg);
  border: 1px solid var(--tl-protect-line);
  border-radius: 10px;
  padding: .7rem .9rem;
  margin-bottom: 1.25rem;
  font-size: .875rem;
  line-height: 1.5;
}
.tl-fixture strong { color: var(--tl-protect); }

/* --- section furniture ---------------------------------------------------- */

.tl-lede {
  font-size: 1.02rem;
  line-height: 1.62;
  max-width: 62ch;
  margin: 0 0 1.5rem;
  color: var(--kit-text-dim, #a8adb8);
}
.tl-lede strong { color: var(--kit-text, #e8eaee); }

.tl-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  margin-bottom: 1.1rem;
  align-items: center;
}
.tl-chipbtn {
  appearance: none;
  background: transparent;
  border: 1px solid var(--tl-rule);
  color: var(--kit-text-dim, #a8adb8);
  border-radius: 999px;
  padding: .34rem .72rem;
  font: inherit;
  font-size: .8125rem;
  cursor: pointer;
  min-height: 34px;
}
.tl-chipbtn:hover { border-color: var(--kit-accent-line); color: var(--kit-text, #e8eaee); }
.tl-chipbtn.is-on {
  background: var(--kit-accent-soft);
  border-color: var(--kit-accent-line);
  color: var(--kit-accent-hover);
}
.tl-count { font-size: .8125rem; color: var(--kit-text-dim, #8a8f9a); margin-left: auto; }

/* --- the place card ------------------------------------------------------- */

.tl-cards { display: grid; gap: .7rem; }
.tl-card {
  border: 1px solid var(--tl-rule);
  border-radius: 12px;
  padding: .95rem 1rem;
  background: rgba(255, 255, 255, .015);
}
.tl-card__top {
  display: flex;
  gap: .75rem;
  align-items: baseline;
  flex-wrap: wrap;
  margin-bottom: .5rem;
}
.tl-card__name {
  font-size: 1.06rem;
  font-weight: 620;
  margin: 0;
  color: var(--kit-text, #e8eaee);
}
.tl-card__drive {
  font-size: .8125rem;
  color: var(--kit-text-dim, #8a8f9a);
  font-variant-numeric: tabular-nums;
}
.tl-card__read {
  font-size: .9rem;
  line-height: 1.5;
  color: var(--kit-text-dim, #a8adb8);
  margin: .1rem 0 .7rem;
}

/* --- the two-axis rating -------------------------------------------------
   The design test is John's Pass: paddle 1 of 5, fish 4 of 5. Every guide that
   collapses those into one number is useless for deciding what to put in the
   car, so the two axes are rendered as two separate labelled rows and there is
   no combined figure anywhere in the app. */
.tl-rating { display: grid; gap: .3rem; margin: 0 0 .6rem; }
.tl-rating__row { display: flex; align-items: center; gap: .55rem; }
.tl-rating__label {
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--kit-text-dim, #8a8f9a);
  width: 3.6rem;
  flex: none;
}
.tl-pips { display: flex; gap: 3px; }
.tl-pip {
  width: 15px;
  height: 5px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .13);
}
.tl-pip.is-on { background: var(--kit-accent); }
.tl-rating__n {
  font-size: .78rem;
  color: var(--kit-text-dim, #8a8f9a);
  font-variant-numeric: tabular-nums;
}

/* --- chips ---------------------------------------------------------------- */

.tl-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin: .1rem 0 .55rem; }
.tl-chip {
  font-size: .75rem;
  padding: .2rem .55rem;
  border-radius: 999px;
  border: 1px solid var(--tl-rule);
  color: var(--kit-text-dim, #a8adb8);
  white-space: nowrap;
}
.tl-chip--kind { border-color: var(--kit-accent-line); color: var(--kit-accent-hover); background: var(--kit-accent-soft); }
.tl-chip--blank { border-color: var(--tl-blank-line); color: var(--tl-blank); background: var(--tl-blank-bg); }
.tl-chip--protect { border-color: var(--tl-protect-line); color: var(--tl-protect); background: var(--tl-protect-bg); }

/* --- the honest blank ----------------------------------------------------- */

.tl-blank {
  border-left: 2px solid var(--tl-blank-line);
  background: var(--tl-blank-bg);
  padding: .5rem .7rem;
  border-radius: 0 7px 7px 0;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--tl-blank);
  margin: .5rem 0;
}
.tl-blank b { color: var(--tl-blank); font-weight: 640; }

/* --- protected animals ---------------------------------------------------- */

.tl-protect {
  border: 1px solid var(--tl-protect-line);
  background: var(--tl-protect-bg);
  border-radius: 10px;
  padding: .85rem 1rem;
  margin: 0 0 .7rem;
}
.tl-protect h4 {
  margin: 0 0 .35rem;
  font-size: .95rem;
  color: var(--tl-protect);
}
.tl-protect p { margin: 0; font-size: .875rem; line-height: 1.55; color: var(--kit-text-dim, #a8adb8); }

/* --- detail rows ---------------------------------------------------------- */

.tl-rows { display: grid; gap: .55rem; margin: .6rem 0 0; }
.tl-row { display: grid; grid-template-columns: 5.5rem 1fr; gap: .7rem; align-items: start; }
.tl-row__k {
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--kit-text-dim, #8a8f9a);
  padding-top: .12rem;
}
.tl-row__v { font-size: .9rem; line-height: 1.55; }
@media (max-width: 460px) {
  .tl-row { grid-template-columns: 1fr; gap: .12rem; }
}

/* --- prose ---------------------------------------------------------------- */

.tl-prose { max-width: 68ch; }
.tl-prose h3 { margin: 1.7rem 0 .5rem; font-size: 1.06rem; }
.tl-prose h4 { margin: 1.2rem 0 .35rem; font-size: .95rem; color: var(--kit-accent-hover); }
.tl-prose p, .tl-prose li { line-height: 1.62; }
.tl-prose ul { padding-left: 1.15rem; }
.tl-prose li { margin: .3rem 0; }
.tl-prose a { color: var(--kit-accent-hover); }
.tl-tablewrap { overflow-x: auto; margin: .8rem 0; }
.tl-tablewrap table { border-collapse: collapse; min-width: 100%; font-size: .85rem; }
.tl-tablewrap th, .tl-tablewrap td {
  text-align: left;
  padding: .45rem .6rem;
  border-bottom: 1px solid var(--tl-rule);
  vertical-align: top;
}
.tl-tablewrap th { color: var(--kit-text-dim, #8a8f9a); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }

/* --- accordion ------------------------------------------------------------ */

details.tl-more { margin-top: .5rem; }
details.tl-more > summary {
  cursor: pointer;
  font-size: .8125rem;
  color: var(--kit-accent-hover);
  list-style: none;
  padding: .3rem 0;
  min-height: 32px;
  display: flex;
  align-items: center;
}
details.tl-more > summary::-webkit-details-marker { display: none; }
details.tl-more > summary::before { content: "▸ "; margin-right: .35rem; }
details.tl-more[open] > summary::before { content: "▾ "; }

/* --- month strip ---------------------------------------------------------- */

.tl-months { display: flex; gap: .3rem; overflow-x: auto; padding-bottom: .4rem; margin-bottom: 1rem; }
.tl-months .tl-chipbtn { flex: none; }

/* --- sources -------------------------------------------------------------- */

.tl-cites { margin: .5rem 0 0; font-size: .78rem; color: var(--kit-text-dim, #8a8f9a); line-height: 1.6; }
.tl-cites a { color: var(--kit-text-dim, #8a8f9a); text-decoration: underline; text-underline-offset: 2px; }
.tl-cites a:hover { color: var(--kit-accent-hover); }

/* --- the field-guide plate grid ------------------------------------------
   The habitat accordion is a plate page, not a text list: two up on a phone,
   tap a plate for the entry. The plates sit on an explicit LIGHT ground, the
   same call the Rig tab made and for a stronger reason here. Measured across
   all 74: against #f7f8f9 the darkest 5% of every plate clears the ground by
   65 L* at worst and never fails, while against the card's own dark ground the
   separation is NEGATIVE on all 74, meaning every plate's own contour is darker
   than the card it would sit on. The Keep? fish get away with dark because that
   set has no near-black subject in it; this one has a frigatebird, a black
   skimmer, a cottonmouth and a bald eagle.
   ------------------------------------------------------------------------- */

/* Breaks out of the card's own 1rem side padding. That padding is right for
   prose and wrong for plates: reclaiming it takes the art box from 154 to 171
   CSS px on a 402 px phone, which is the difference the §5 re-check is run
   against, and edge-to-edge plates read as a page rather than as a widget. */
.tl-plategrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: .5rem;
  margin: .5rem -1rem 0;
}
.tl-plategrid__note {
  margin: .5rem 0 0;
  font-size: .75rem;
  color: var(--kit-text-dim, #8a8f9a);
}
/* Flex column rather than block, and the reason is a button quirk worth naming:
   a <button> centres its own content vertically, so in a row where one card is
   taller (a Caution chip adds a line) the shorter card's plate floated 13px down
   and the grid read as misaligned. `display: block` does not override it. */
.tl-plate {
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start;
  width: 100%; text-align: left; padding: 0; cursor: pointer;
  border: 1px solid var(--tl-rule); border-radius: 10px;
  background: rgba(255, 255, 255, .022);
  overflow: hidden;
  transition: border-color .12s ease;
}
.tl-plate:hover { border-color: var(--kit-accent-line); }
.tl-plate.is-on { border-color: var(--kit-accent); background: var(--kit-accent-soft); }
/* `flex: none` and the two `min-*: 0` are load-bearing, not defensive. A flex
   item's automatic minimum size is its CONTENT size, and the plate is a 640px
   intrinsic image, so without them the square aspect-ratio loses to the image
   and the box renders 170 wide by 650 tall. */
.tl-plate__art {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; flex: none; min-height: 0;
  padding: .3rem; background: #f7f8f9;
}
.tl-plate__art img {
  display: block; min-width: 0; min-height: 0;
  max-width: 100%; max-height: 100%; object-fit: contain;
}
/* An entry with no plate keeps its slot. The sand says "not drawn yet", which is
   the same thing this app's blanks say everywhere else, rather than reading as a
   broken image or a missing record. */
.tl-plate__art--none {
  background: var(--tl-blank-bg);
  border-bottom: 1px solid var(--tl-blank-line);
  align-items: flex-start;
}
.tl-plate__art--none span {
  padding: .45rem .55rem; font-size: .72rem; line-height: 1.45;
  color: var(--tl-blank); font-style: italic;
  display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;
}
.tl-plate__name {
  display: block; padding: .4rem .5rem .5rem;
  font-size: .8rem; line-height: 1.35; font-weight: 600;
  color: var(--kit-text, #e8eaee);
}
.tl-plate__chip { margin: 0 .5rem .5rem; }

/* The opened entry, below the grid. */
.tl-guidecard { margin-top: .6rem; border-left: 2px solid var(--kit-accent-line); }
.tl-guidecard__latin { font-weight: 400; font-size: .875rem; color: var(--kit-text-dim, #8a8f9a); }
.tl-guideplate {
  margin: .7rem 0 .2rem; padding: .5rem; border-radius: 10px;
  background: #f7f8f9; border: 1px solid var(--tl-rule);
  max-width: 26rem;
}
.tl-guideplate img {
  display: block; margin: 0 auto; width: auto; height: auto;
  max-width: min(100%, 21rem); max-height: 21rem;
}
/* Dark type, because this caption sits ON the light plate ground rather than on
   the card. Taking the app's own --kit-text here would put near-white text on
   near-white and lose the whole caption. */
.tl-guideplate__cap {
  margin-top: .5rem; font-size: .78rem; line-height: 1.5; color: #3c4148;
}
.tl-guideplate__cap b {
  font-weight: 640; letter-spacing: .03em; text-transform: uppercase;
  font-size: .68rem; color: #0d6f78;
}
.tl-guideplate__limit {
  display: block; margin-top: .3rem; font-size: .74rem; line-height: 1.5; color: #6b5327;
}
.tl-guideplate__prov {
  display: block; margin-top: .3rem; font-size: .72rem; line-height: 1.5; color: #6d727b;
}

/* --- habitat look-fors ---------------------------------------------------- */

.tl-lookfors { display: grid; gap: .4rem; margin-top: .5rem; }
.tl-lookfor { font-size: .875rem; line-height: 1.5; }
.tl-lookfor b { color: var(--kit-text, #e8eaee); font-weight: 600; }
.tl-lookfor i { color: var(--kit-text-dim, #8a8f9a); font-style: italic; }
.tl-lookfor em { color: var(--kit-accent-hover); font-style: normal; }

/* The references' house marker for an unverified fact, translated by the
   compiler from their bolded literal "blank" into the app's blank treatment. */
.tl-unknown {
  color: var(--tl-blank);
  font-style: normal;
  white-space: nowrap;
}

/* A field-guide entry's `note`. On a `danger` entry this is the safety line and
   it gets the protected treatment; the rest are colour, and stay quiet. */
.tl-protectnote {
  margin-top: .35rem;
  padding: .45rem .6rem;
  border-left: 2px solid var(--tl-protect-line);
  background: var(--tl-protect-bg);
  border-radius: 0 6px 6px 0;
  font-size: .84rem;
  line-height: 1.5;
  color: var(--tl-protect);
}
.tl-note {
  margin-top: .3rem;
  font-size: .84rem;
  line-height: 1.5;
  color: var(--kit-text-dim, #8a8f9a);
}

/* ---------------------------------------------------------------------------
   Plan: the phase-2 ranker
   --------------------------------------------------------------------------- */

/* The mode picker is the first thing on the tab and deliberately large. Mode is
   the user's call, never inferred, so the choice has to look like a choice
   rather than a filter chip. Three since 2026-08-06, which fits one row on a
   phone where five wrapped awkwardly. */
.tl-plan__modes {
  display: grid; gap: .5rem; margin: 0 0 .9rem;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
}
.tl-mode {
  display: grid; gap: .18rem; text-align: left; cursor: pointer;
  padding: .6rem .7rem; border-radius: 10px;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .022);
  color: var(--kit-text-dim, #a8adb8); font: inherit;
}
.tl-mode:hover { border-color: var(--kit-accent-line); }
.tl-mode.is-on {
  border-color: var(--kit-accent); background: var(--kit-accent-soft);
}
.tl-mode__label { font-size: .95rem; font-weight: 640; color: var(--kit-text, #e8eaee); }
.tl-mode.is-on .tl-mode__label { color: var(--kit-accent-hover); }
.tl-mode__reads { font-size: .775rem; line-height: 1.35; }
/* MEASURED ON A PHONE 2026-08-07: at 375px the three buttons wrapped 2 + 1 and
   the orphan sat 24px shorter than its neighbours, because the `reads` line
   takes two lines in a 160px column and one in the wider third slot. Two up
   with equal rows and the third spanning the width is two rows rather than
   three, and nothing is ragged. */
@media (max-width: 30rem) {
  .tl-plan__modes { grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; }
  .tl-plan__modes .tl-mode:last-child { grid-column: 1 / -1; }
  .tl-mode__reads { font-size: .74rem; }
}

/* Five radius chips plus the label overflow a 375px phone, and the toolbar
   clipped rather than expanding, which put the 60 min chip out of reach. The
   group has to wrap internally, not just as one item in the toolbar. */
.tl-plan__group { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; font-size: .8125rem; color: var(--kit-text-dim, #8a8f9a); }
.tl-datefield {
  display: flex; align-items: center; gap: .45rem;
  font-size: .8125rem; color: var(--kit-text-dim, #8a8f9a);
}
.tl-datefield input {
  font: inherit; color: var(--kit-text, #e8eaee); color-scheme: dark;
  background: rgba(255, 255, 255, .04); border: 1px solid var(--tl-rule);
  border-radius: 7px; padding: .3rem .45rem;
}
.tl-boat { display: flex; align-items: center; gap: .4rem; font-size: .8125rem; color: var(--kit-text-dim, #8a8f9a); cursor: pointer; }
.tl-boat input { accent-color: var(--kit-accent); }
/* Shore mode replaces the checkbox with the reason there is no checkbox. A
   disabled control invites you to wonder what it would do; a sentence answers
   it. */
.tl-boat.is-moot { display: block; max-width: 26rem; line-height: 1.4; opacity: .8; cursor: default; }
/* MEASURED AT 13x13 ON A PHONE. It is the control that widens the search to
   five destinations, and it was the smallest target on the screen. */
.tl-boat { display: flex; align-items: center; gap: .5rem; min-height: 44px; cursor: pointer; }
.tl-boat input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--kit-accent); flex: none; }

/* Salt or fresh sits under the fishing modes only, so it reads as a second
   question about the mode above rather than a fourth mode. */
.tl-toolbar--sub { margin-top: -.5rem; padding-top: 0; border-top: 0; }

.tl-plan__head {
  margin: .3rem 0 .9rem; padding: .6rem .75rem;
  border-left: 2px solid var(--kit-accent-line); background: var(--kit-accent-soft);
  border-radius: 0 8px 8px 0; font-size: .875rem;
}
.tl-plan__sun { margin-top: .15rem; font-size: .8rem; color: var(--kit-text-dim, #8a8f9a); }

.tl-plan__count { margin-top: .15rem; font-size: .8rem; color: var(--kit-text-dim, #8a8f9a); }

/* ---------------------------------------------------------------------------
   The three checks this app does not make
   --------------------------------------------------------------------------- */

/* FIRST on the screen, and the placement is the point. Phase 2 said the same
   thing in a provenance paragraph at the bottom, where it read as a footnote
   about data sourcing rather than as three things that cancel the day.

   It is deliberately NOT in the warning colour. Sand means "the research left a
   blank here", and this is not a blank: it is a boundary the app chose, stated
   plainly. Giving it an alarm treatment on every single load is how a reader
   learns to skim the alarms. */
.tl-outside {
  margin: 0 0 1.1rem; padding: .75rem .85rem; border-radius: 10px;
  border: 1px solid var(--kit-accent-line); background: var(--kit-accent-soft);
}
.tl-outside__h { margin: 0 0 .25rem; font-size: .95rem; color: var(--kit-accent-hover); }
.tl-outside__lede { margin: 0 0 .6rem; font-size: .82rem; line-height: 1.5; }

/* One row per check: the label, the threshold, the link. Everything else is in
   the disclosure below, because this panel is read on every single load and it
   was costing two screens before the answer. */
.tl-outside__rows { display: grid; gap: .5rem; }
.tl-outside__row {
  display: grid; grid-template-columns: 4.6rem 1fr; gap: .1rem .6rem;
  padding: .45rem .55rem; border-radius: 8px;
  border: 1px solid var(--tl-rule); background: rgba(0, 0, 0, .16);
}
.tl-outside__label {
  grid-row: span 2; align-self: start; padding-top: .1rem;
  font-size: .72rem; letter-spacing: .05em; text-transform: uppercase;
  color: var(--kit-text-dim, #8a8f9a); font-weight: 600;
}
.tl-outside__limit { font-size: .82rem; line-height: 1.4; font-weight: 560; }
.tl-outside__link {
  font-size: .8rem; font-weight: 560; padding: .45rem 0 .3rem;
  /* Measured at 26px on a phone. These are the three links the panel exists to
     send you to, so they clear a thumb. */
  min-height: 32px;
  /* Measured as rgb(158,158,255) on a phone: the browser's visited-link
     lavender, on the three links that decide whether the trip happens. */
  color: var(--kit-accent-hover);
}
@media (max-width: 24rem) {
  .tl-outside__row { grid-template-columns: 1fr; }
  .tl-outside__label { grid-row: auto; }
}

.tl-outside__whys { margin-top: .6rem; }
.tl-outside__whys > summary {
  font-size: .78rem; color: var(--kit-accent-hover); cursor: pointer;
  padding: .5rem 0; min-height: 32px;
}
.tl-outside__why { margin: .5rem 0 0; font-size: .78rem; line-height: 1.5; color: var(--kit-text-dim, #8a8f9a); }
.tl-outside__why b { color: var(--kit-text, #e8eaee); font-weight: 600; }
.tl-outside__note { display: block; margin-top: .2rem; color: var(--tl-blank); }
.tl-outside__checked { display: block; margin-top: .1rem; }

/* ---------------------------------------------------------------------------
   The three groups
   --------------------------------------------------------------------------- */

/* Every heading names its own scope, because a band that reads as a verdict on
   the day is the overclaim this whole screen was rebuilt against.

   NO RED-AMBER-GREEN, and not only as a house rule: a place that is out on the
   tide is not a warning about anything, it is a fact about Saturday. Clear takes
   the app accent, possible takes sand (which already means "the research
   qualified this" everywhere else in the app), and unavailable takes the neutral
   rule colour and nothing else. */
.tl-group { margin: 1.4rem 0 0; }
.tl-group__h {
  display: flex; align-items: baseline; gap: .5rem;
  margin: 0 0 .1rem; font-size: .95rem;
}
.tl-group__h--sub { margin-top: 1.1rem; font-size: .875rem; }
.tl-group__n {
  font-size: .75rem; font-variant-numeric: tabular-nums;
  padding: .05rem .4rem; border-radius: 99px;
  border: 1px solid var(--tl-rule); color: var(--kit-text-dim, #8a8f9a);
}
.tl-group__lede { margin: 0 0 .6rem; font-size: .8rem; line-height: 1.5; color: var(--kit-text-dim, #8a8f9a); }
.tl-group--clear .tl-group__h { color: var(--kit-accent-hover); }
.tl-group--possible .tl-group__h { color: var(--tl-blank); }
.tl-group--unavailable .tl-group__h { color: var(--kit-text-dim, #8a8f9a); }

.tl-tripcard { border-left: 2px solid var(--tl-rule); }
.tl-tripcard--clear { border-left-color: var(--kit-accent); }
.tl-tripcard--possible { border-left-color: var(--tl-blank-line); }
.tl-tripcard--unavailable { opacity: .78; }

/* The one sentence about what the tide actually did. It replaced a reason line
   that sat under a score, where it read as a justification of a rank. */
.tl-tideline { margin: .35rem 0 .5rem; font-size: .9rem; line-height: 1.55; }
.tl-blocked { margin: .35rem 0 .5rem; font-size: .9rem; line-height: 1.55; color: var(--kit-text-dim, #a8adb8); }
.tl-trim { margin: .15rem 0 .4rem; font-size: .8rem; color: var(--kit-text-dim, #8a8f9a); }

.tl-destinations { margin-top: 1.6rem; }
.tl-destinations > summary { color: var(--kit-accent-hover); font-size: .9rem; }
.tl-destinations__hint { color: var(--kit-text-dim, #8a8f9a); font-size: .8rem; font-weight: 400; }

.tl-warn {
  margin: .4rem 0; padding: .5rem .65rem; border-radius: 8px;
  border: 1px solid var(--tl-blank-line); background: var(--tl-blank-bg);
  font-size: .85rem; line-height: 1.5; color: var(--tl-blank);
}
.tl-note--advisory, .tl-note--assumption, .tl-note--caveat, .tl-note--info, .tl-note--gauge {
  margin: .3rem 0; font-size: .8125rem; line-height: 1.5;
  color: var(--kit-text-dim, #8a8f9a);
}
.tl-note--assumption { color: var(--tl-blank); }
/* The per-place gauge limitation from the authored gauge table. It rides under
   the residual because a bare station name reads far more local than the source
   permits: Clearwater Beach stands in for Anclote Key from 20.79 km away. */
.tl-note--gauge { font-style: italic; opacity: .85; }

/* ---------------------------------------------------------------------------
   Keep?
   --------------------------------------------------------------------------- */

/* The colours here are the app's existing vocabulary rather than a traffic
   light. Rose already means "legally protected, a prohibition rather than a goal
   state", and a closed season is exactly that. Sand already means "the research
   could not settle this". Accent means open. */
.tl-keep__warn {
  margin: 0 0 .9rem; padding: .55rem .7rem; border-radius: 8px;
  border: 1px solid var(--tl-protect-line); background: var(--tl-protect-bg);
  font-size: .82rem; line-height: 1.5;
}
.tl-keep__boundary { margin: -.35rem 0 .8rem; font-size: .8rem; line-height: 1.5; color: var(--kit-text-dim, #8a8f9a); }
.tl-keep__hint { margin: .8rem 0; font-size: .85rem; color: var(--kit-text-dim, #8a8f9a); }

.tl-search {
  flex: 1 1 12rem; min-width: 9rem; padding: .4rem .6rem; border-radius: 8px;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .04);
  color: inherit; font: inherit; font-size: .9rem;
}

/* MEASURED ON A PHONE 2026-08-07: at 11rem this fell to ONE column at 375px,
   because 343px of usable width cannot take two 176px tracks. Twenty-one tiles
   in a single column is a scroll, not a grid, and the grid exists so the common
   case is one tap. At 9rem it is two columns on both phones. */
.tl-keep__grid {
  display: grid; gap: .4rem; margin: .8rem 0 1rem;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
}
.tl-keeptile {
  display: flex; flex-direction: column; gap: .15rem; text-align: left;
  padding: .5rem .6rem; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .022);
  color: inherit; font: inherit;
}
.tl-keeptile.is-on { border-color: var(--kit-accent); background: var(--kit-accent-soft); }
.tl-keeptile__name { font-size: .85rem; line-height: 1.3; }
.tl-keeptile__v { font-size: .72rem; letter-spacing: .03em; text-transform: uppercase; font-weight: 620; }
.tl-keeptile--yes .tl-keeptile__v { color: var(--kit-accent); }
.tl-keeptile--no .tl-keeptile__v { color: var(--tl-protect); }
.tl-keeptile--unknown .tl-keeptile__v { color: var(--tl-blank); }

.tl-keepcard { border-left: 2px solid var(--tl-rule); }
.tl-keepcard--yes { border-left-color: var(--kit-accent); }
.tl-keepcard--no { border-left-color: var(--tl-protect); }
.tl-keepcard--unknown { border-left-color: var(--tl-blank-line); }
.tl-keepcard__v { font-size: .78rem; letter-spacing: .03em; text-transform: uppercase; font-weight: 640; white-space: nowrap; }
.tl-keepcard__v--yes { color: var(--kit-accent); }
.tl-keepcard__v--no { color: var(--tl-protect); }
.tl-keepcard__v--unknown { color: var(--tl-blank); }
/* The legal block comes first and is visually the card. Identification and
   tackle are underneath, which is the whole reversal. */
.tl-keepcard__legal { margin: .4rem 0 .6rem; }
.tl-keepcard__how { margin-top: .2rem; font-size: .8rem; color: var(--kit-text-dim, #8a8f9a); }
/* The source for THIS figure, on the same row as the figure. A slot limit and a
   season can come from different pages and go stale on different days, and one
   citation at the bottom of the card cannot say which. */
.tl-keepcard__src { display: block; margin-top: .15rem; font-size: .72rem; color: var(--kit-text-dim, #8a8f9a); }
.tl-keepcard__varies { color: var(--tl-blank); font-size: .8rem; }
.tl-keepcard__note { margin: .35rem 0; font-size: .85rem; line-height: 1.5; }
/* The sentence the answer rests on, quoted, so a reader can check the app
   against the reference without leaving the card. */
.tl-keepcard__because {
  margin: .25rem 0; font-size: .78rem; line-height: 1.5; font-style: italic;
  color: var(--kit-text-dim, #8a8f9a);
}

/* The illustration. It sits between the legal answer and the identification
   details, which is where a person holding a fish looks next, and it is capped
   in HEIGHT rather than width so it can never push that answer off a phone.
   The legal block is above it in the source order, so it is never displaced.

   The frame is a FIXED height and `contain`, which means every plate is the same
   size and each fish is drawn at its own proportions inside it. That is
   deliberate: the twenty-one canvases are square, every fish is centred, and the
   ink runs from 21% of the canvas height (scaled sardine) to 78% (the Mayan
   cichlid and Oscar pair). A box tuned to a snook would cut the top and bottom
   off the deep-bodied fish, and cropping a dorsal fin off an identification
   plate defeats the only job it has. So the sardine sits small in its frame and
   the cichlid nearly fills it, exactly as they do on a printed guide page. */
.tl-fishart {
  margin: .7rem 0 .2rem; padding: .5rem .6rem .55rem;
  border: 1px solid var(--tl-rule); border-radius: 10px;
  background: rgba(0, 0, 0, .16);
  /* So the frame stays a plate on a wide window instead of a 1,000px band with
     a fish adrift in the middle of it. */
  max-width: 26rem;
}
.tl-fishart__img {
  display: block; width: 100%; height: 13rem; object-fit: contain;
  /* Transparent art on the card's own ground, never a white plate. */
  background: none;
}
.tl-fishart__cap {
  margin-top: .45rem; font-size: .8rem; line-height: 1.5;
  color: var(--kit-text, #e6e8ec);
}
.tl-fishart__cap b {
  font-weight: 640; letter-spacing: .03em; text-transform: uppercase;
  font-size: .7rem; color: var(--kit-accent);
}
/* Provenance, in the register the rest of the app uses for a source line. */
.tl-fishart__prov {
  display: block; margin-top: .3rem; font-size: .72rem; line-height: 1.5;
  color: var(--kit-text-dim, #8a8f9a);
}
@media (min-width: 46rem) {
  .tl-fishart__img { height: 18rem; }
}

.tl-empty {
  padding: .95rem 1.05rem; border-radius: 10px;
  border: 1px solid var(--tl-blank-line); background: var(--tl-blank-bg);
}
.tl-empty h3 { margin: 0 0 .4rem; font-size: 1rem; color: var(--tl-blank); }
.tl-empty p { margin: .35rem 0; font-size: .875rem; line-height: 1.55; }
.tl-empty ul { margin: .5rem 0; padding-left: 1.15rem; font-size: .875rem; }
.tl-empty li { margin: .25rem 0; }
.tl-empty__rule { color: var(--kit-text-dim, #a8adb8); font-size: .8125rem !important; }

.tl-ledger { margin-top: 1rem; }
.tl-ledger__h { margin: .9rem 0 .1rem; font-size: .85rem; color: var(--kit-accent-hover); }
.tl-ledger .tl-row { grid-template-columns: 11rem 1fr; }

.tl-prov {
  margin-top: 1.6rem; padding-top: .9rem; border-top: 1px solid var(--tl-rule);
  font-size: .8125rem; line-height: 1.55; color: var(--kit-text-dim, #8a8f9a);
}
.tl-prov p { margin: .4rem 0; }
.tl-prov b { color: var(--kit-text, #e8eaee); }

@media (max-width: 30rem) {
    .tl-ledger .tl-row { grid-template-columns: 1fr; gap: .15rem; }
}

/* The ledger reuses the two-column row, but a place name is a name and not a
   field label, so it does not take the label's uppercase treatment. */
.tl-ledger .tl-row__k { text-transform: none; letter-spacing: 0; font-size: .85rem; }

/* On a phone the radius chips were wrapping "10" and "min" onto two lines. */
.tl-plan__group .tl-chipbtn { white-space: nowrap; }

/* The boat-day guide's own Bring section, repeated as conditions rather than
   resolved into one word: several of its conditions are facts the app does not
   hold, and picking one for the reader is how the invented version got it
   wrong at the St. Petersburg waterfront. */
.tl-bring {
  margin: .5rem 0; padding: .55rem .7rem; border-radius: 8px;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .022);
  font-size: .8125rem; line-height: 1.5;
}
.tl-bring > b { display: block; margin-bottom: .3rem; font-size: .75rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--kit-text-dim, #8a8f9a); font-weight: 600; }
.tl-bring__row { display: grid; grid-template-columns: 11rem 1fr; gap: .6rem; margin: .2rem 0; }
.tl-bring__row > span:first-child { color: var(--kit-accent-hover); }
@media (max-width: 30rem) { .tl-bring__row { grid-template-columns: 1fr; gap: .1rem; } }

/* ---------------------------------------------------------------------------
   The date check, on the Places tab
   --------------------------------------------------------------------------- */

/* This is what social mode became. Travis never organises a boat day; he gets
   invited and the place is already named, so this is a lookup and it is styled
   as one: no score bar, no rank number, no comparison to anything. It lives on
   the place card because the place is the thing he was told. */
.tl-daycheck { margin-top: .55rem; }
.tl-daycheck > summary { color: var(--kit-accent-hover); }
.tl-daycheck .tl-datefield { margin: .5rem 0 .1rem; }
.tl-daycheck__hint {
  margin: .45rem 0 0; font-size: .8rem; line-height: 1.5;
  color: var(--kit-text-dim, #8a8f9a);
}
.tl-daycheck__out { margin-top: .5rem; }
/* Not red. A prohibited stage is a fact about the water, not an alarm, and the
   app's rule is that the warnings are the warnings and they are in sand. */
.tl-daycheck__no { color: var(--tl-blank); }

/* ---------------------------------------------------------------------------
   What do we throw
   --------------------------------------------------------------------------- */

/* The half the date check was missing. Only the "strongest this month" heading
   takes the accent, and the undotted group stays in plain text rather than
   dimmed: the table's own caption says a blank does not mean the species is
   absent, and greying those out would say the opposite in a colour. */
.tl-tackle {
  margin: .6rem 0; padding: .6rem .75rem; border-radius: 8px;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .022);
}
.tl-tackle > b {
  display: block; margin-bottom: .2rem; font-size: .75rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--kit-text-dim, #8a8f9a); font-weight: 600;
}
.tl-tackle__intro { margin: 0 0 .7rem; font-size: .82rem; line-height: 1.5; color: var(--kit-text-dim, #a8adb8); }
.tl-tackle__h {
  display: flex; align-items: baseline; gap: .45rem;
  margin: .9rem 0 .15rem; font-size: .8rem; letter-spacing: .02em;
  color: var(--kit-text-dim, #8a8f9a); font-weight: 600;
}
.tl-tackle__h:first-of-type { margin-top: .2rem; }
.tl-tackle__n {
  font-size: .7rem; font-variant-numeric: tabular-nums; padding: .02rem .35rem;
  border-radius: 99px; border: 1px solid var(--tl-rule); font-weight: 400;
}
/* The caption from the reference, carried verbatim, because it is the reason
   this cannot be read as a season: the dot is scoped to beginners. */
.tl-tackle__lede { margin: .1rem 0 .5rem; font-size: .76rem; line-height: 1.45; font-style: italic; color: var(--kit-text-dim, #8a8f9a); }
.tl-tackle__fish { margin: .45rem 0; padding-left: .55rem; border-left: 2px solid var(--tl-rule); }
.tl-tackle__fish--on { border-left-color: var(--kit-accent); }
.tl-tackle__name { font-size: .875rem; font-weight: 600; margin-bottom: .15rem; }
.tl-tackle__as { font-weight: 400; font-size: .78rem; color: var(--kit-text-dim, #8a8f9a); }
.tl-tackle__row { display: grid; grid-template-columns: 3.4rem 1fr; gap: .5rem; margin: .1rem 0; font-size: .82rem; line-height: 1.5; }
.tl-tackle__row > span:first-child {
  font-size: .7rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--kit-text-dim, #8a8f9a); padding-top: .18rem;
}
/* Named, not dropped. A verdict that says "and sharks" and a card that silently
   omits them is the same silent absence this app forbids everywhere else. */
.tl-tackle__excl {
  margin-top: .7rem; padding-top: .5rem; border-top: 1px solid var(--tl-rule);
  font-size: .78rem; line-height: 1.5; color: var(--kit-text-dim, #8a8f9a);
}
.tl-tackle__excl b { color: var(--tl-blank); }
.tl-tackle__rest { margin-top: .8rem; }
.tl-tackle__rest > summary { font-size: .8rem; color: var(--kit-accent-hover); cursor: pointer; padding: .35rem 0; }
.tl-tackle__rest > summary span { color: var(--kit-text-dim, #8a8f9a); }
.tl-tackle__rest .tl-tackle__h:first-of-type { margin-top: .4rem; }
/* The Keep? per-figure source links, and the Fish|Hunt link in the warning:
   the same lavender the outside links had. */
.tl-keepcard__src a, .tl-keep__warn a { color: var(--kit-accent-hover); }
.tl-tackle__note { margin: .5rem 0 0; font-size: .76rem; line-height: 1.5; color: var(--kit-text-dim, #8a8f9a); }
@media (max-width: 30rem) { .tl-tackle__row { grid-template-columns: 1fr; gap: .05rem; } }

/* ---------------------------------------------------------------------------
   The map link, and the honesty that travels with it
   --------------------------------------------------------------------------- */

/* Contract section 16. The qualifier is on its own line rather than in a
   tooltip, because twenty-three of the twenty-eight positions are map-derived
   and a caveat nobody can see on a phone is not a caveat. `flex-basis: 100%`
   is what wraps it under the row without the link renderer needing to know
   which card it is on: one helper, two surfaces. */
.tl-placelinks {
  display: flex; flex-wrap: wrap; align-items: center; gap: .45rem .8rem;
  margin-top: .55rem;
}
.tl-maps, .tl-linkbtn {
  font-size: .8rem; color: var(--kit-accent-hover); text-decoration: none;
  border: 1px solid var(--tl-rule); border-radius: 99px; padding: .22rem .6rem;
  background: none; cursor: pointer; font-family: inherit; white-space: nowrap;
}
.tl-maps:hover, .tl-linkbtn:hover { border-color: var(--kit-accent); }
.tl-maps__note {
  /* `order: 1` puts the qualifier after BOTH buttons rather than between them:
     the helper emits link-then-note and the row also carries "Can we keep it?",
     which the note was splitting apart at 375 wide. */
  order: 1; flex-basis: 100%; margin: 0; font-size: .74rem; line-height: 1.45;
  color: var(--tl-blank);
}

/* ---------------------------------------------------------------------------
   What is here: the two halves, ordered by mode
   --------------------------------------------------------------------------- */

/* Contract section 18. The whole thing is one disclosure on a trip card,
   because the Plan tab renders up to twenty-eight of them and the tackle
   panel's measured 2,645px on each would be the same mistake with a
   multiplier. Neither half is ever deleted by mode; the one the mode does not
   lead with folds. */
.tl-holds { margin-top: .6rem; }
.tl-holds > summary {
  font-size: .82rem; color: var(--kit-accent-hover); cursor: pointer; padding: .35rem 0;
}
.tl-holds__n { color: var(--kit-text-dim, #8a8f9a); font-size: .78rem; }
.tl-holds__other { margin-top: .6rem; }
.tl-holds__other > summary {
  font-size: .8rem; color: var(--kit-accent-hover); cursor: pointer; padding: .35rem 0;
}

.tl-wild {
  margin: .6rem 0; padding: .6rem .75rem; border-radius: 8px;
  border: 1px solid var(--tl-rule); background: rgba(255, 255, 255, .022);
}
.tl-wild > b {
  display: block; margin-bottom: .2rem; font-size: .75rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--kit-text-dim, #8a8f9a); font-weight: 600;
}
.tl-wild__e { margin: .45rem 0; padding-left: .55rem; border-left: 2px solid var(--tl-rule); }
/* Rose, which is what this app already means by a prohibition. Not red-amber-
   green: a stingray on the flat is not a warning about the day. */
.tl-wild__e--danger { border-left-color: var(--tl-protect-line); }
.tl-wild__name { font-size: .875rem; font-weight: 600; line-height: 1.4; }
.tl-wild__name i { font-weight: 400; font-style: italic; color: var(--kit-text-dim, #8a8f9a); }
.tl-wild__coll {
  font-size: .68rem; font-weight: 400; letter-spacing: .04em; text-transform: uppercase;
  color: var(--kit-text-dim, #8a8f9a);
}
.tl-wild__when { font-size: .78rem; line-height: 1.45; color: var(--kit-accent-hover); }
.tl-wild__where { font-size: .82rem; line-height: 1.5; }
.tl-wild__sure { font-size: .8rem; line-height: 1.5; color: var(--kit-text-dim, #a8adb8); }
/* The first-minute steps, one tap under the hazard sentence. This is a fold of
   the PROCEDURE, never of the warning: the name and what it does are always on
   screen, which is the rule the caution band exists to keep. */
.tl-wild__first > summary {
  font-size: .76rem; color: var(--tl-protect); cursor: pointer; padding: .2rem 0 0;
}
.tl-wild__first { margin-top: .15rem; }
/* The caution row's disclosure carries the steps, then identification. Measured
   into this shape at 375 wide on 2026-08-08: rendering the caution band like the
   notable band put Fort De Soto's panel at 9,377px, 9,272 of it above a fold
   that band is not allowed to use. */
.tl-wild__steps { margin-bottom: .3rem; }
.tl-wild__first > summary { padding: .25rem 0; }

/* ---------------------------------------------------------------------------
   Rig
   --------------------------------------------------------------------------- */

.tl-seq__group {
  margin: 1.8rem 0 .6rem; font-size: .78rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--kit-text-dim, #8a8f9a);
}
.tl-seq__group:first-of-type { margin-top: 1.2rem; }

.tl-seq__code {
  display: inline-block; margin-right: .45rem; padding: .08rem .32rem;
  border: 1px solid var(--kit-accent-line); border-radius: 5px;
  font-size: .7rem; font-weight: 640; letter-spacing: .05em;
  color: var(--kit-accent); vertical-align: .1em;
}
.tl-seq__lede { margin-top: .45rem; }
.tl-seq__notes { margin-top: 1rem; padding-top: .8rem; border-top: 1px solid var(--tl-rule); }

.tl-steps { list-style: none; margin: .7rem 0 0; padding: 0; }
.tl-step + .tl-step { margin-top: 1.4rem; padding-top: 1.2rem; border-top: 1px solid var(--tl-rule); }
.tl-step__head { display: flex; gap: .6rem; align-items: baseline; }
.tl-step__n {
  flex: 0 0 auto; min-width: 1.5rem; padding: .1rem .3rem;
  border-radius: 5px; background: var(--kit-accent-soft);
  font-size: .78rem; font-weight: 640; text-align: center; color: var(--kit-accent);
}
.tl-step__text { line-height: 1.55; }

/* The one place in this app where art does NOT sit on the card's own ground.
   These plates are near-black ink line with a coded working line over it, and on
   this background the ink vanishes. #f7f8f9 is the displayGrounds value the
   batch manifest declares, not a colour picked here. */
.tl-step__plate {
  margin: .7rem 0 0; padding: .4rem; border-radius: 10px;
  background: #f7f8f9; border: 1px solid var(--tl-rule);
}
.tl-step__plate img {
  display: block; margin: 0 auto;
  /* Both caps, and `auto` on both axes, so the image scales inside whichever
     bites and never distorts. A wide sequence (the double uni is 2.9:1) hits the
     width cap; a tall one (the popping cork rig is 0.44:1, because by step six
     the assembly runs the full frame) hits the height cap instead of turning
     into six screens of scroll. Every plate in a sequence shares one frame, so
     they all shrink by the same factor and the hardware stays anchored. */
  width: auto; height: auto;
  max-width: min(100%, 22.5rem); max-height: 21rem;
}
