/* Municipal Codes — search
   Palette lifted from TX LEO REF (Color.kt / AppTheme.swift) so the two read as
   one family. The hex values are the exact float colours the apps ship. */

:root {
  --bg:      #0B1220;   /* TxBackground */
  --card:    #131D30;   /* TxCard       */
  --border:  #22324C;   /* TxBorder     */
  --gold:    #D4A517;   /* TxGold       */
  --green:   #30DF66;   /* TxGreen      */
  --dim:     #8C8C8C;   /* TxDimText    */
  --white:   #FFFFFF;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
          Arial, sans-serif;

  --wrap: 860px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--white);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  /* An officer reading this one-handed at night is the design target. */
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 16px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 16px; top: 12px;
  z-index: 20;
  background: var(--gold);
  color: var(--bg);
  padding: 10px 14px;
  border-radius: 8px;
  font-weight: 700;
}

/* ------------------------------------------------------------------ header */

.masthead {
  padding: 28px 0 20px;
  border-bottom: 1px solid var(--border);
}

.eyebrow {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
}

/* The city name is plain text with one list loaded and a picker button with
   more. Nothing about the header moves when the second city arrives - the same
   text sits in the same place, and grows a chevron. */
.city-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* -8px left so the label stays optically flush with the H1 below it,
     while the tap target still reaches past it on both sides. */
  margin-left: -8px;
  padding: 6px 8px;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--gold);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.city-btn:hover, .city-btn:focus-visible {
  background: rgba(212, 165, 23, 0.12);
  outline: none;
}
.city-btn-chevron {
  width: 14px; height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

h1 {
  margin: 8px 0 0;
  font-size: clamp(28px, 7vw, 40px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.lede {
  margin: 10px 0 0;
  max-width: 58ch;
  color: var(--dim);
  font-size: 14.5px;
}

/* ------------------------------------------------------------------ search */

/* Sticky because the result list is long and the search box is the only
   control on the page. Scrolling away from it would mean scrolling back. */
.searchbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 14px 0 10px;
}

.field {
  position: relative;
  display: flex;
  align-items: center;
}

.field-icon {
  position: absolute;
  left: 14px;
  width: 18px; height: 18px;
  fill: none;
  stroke: var(--dim);
  stroke-width: 2;
  stroke-linecap: round;
  pointer-events: none;
}

#q {
  width: 100%;
  /* 52px tall: a glove-and-steering-wheel tap target, not a desktop one. */
  height: 52px;
  padding: 0 44px 0 42px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--white);
  font-family: var(--sans);
  font-size: 16px;          /* 16px or iOS zooms the page on focus */
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
#q::placeholder { color: var(--dim); }
#q:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(212, 165, 23, 0.18);
}
/* The browser's own clear affordance would sit under ours. */
#q::-webkit-search-decoration,
#q::-webkit-search-cancel-button { -webkit-appearance: none; }

.clear {
  position: absolute;
  right: 6px;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: none;
  border: 0;
  border-radius: 10px;
  color: var(--dim);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.clear:hover, .clear:focus-visible { color: var(--white); outline: none; background: var(--border); }

.count {
  margin: 10px 2px 0;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
  min-height: 1em;   /* reserve the line so results do not jump on first keystroke */
}
.count b { color: var(--gold); font-weight: 700; }

/* ----------------------------------------------------------------- results */

main { padding-bottom: 8px; outline: none; }

.list {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.row {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 14px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: start;
}

.row-code {
  grid-column: 1;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--gold);
}

.row-desc {
  grid-column: 1 / -1;
  grid-row: 2;
  font-size: 15px;
  /* The source list is shouted in caps. Sentence-ish casing is far easier to
     scan, and the original text is preserved verbatim for copying. */
  text-transform: none;
}

.row-ref {
  grid-column: 1 / -1;
  grid-row: 3;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
  word-break: break-word;
}
.row-ref:empty { display: none; }

.copy {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: start;
  min-width: 64px;
  height: 32px;
  padding: 0 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.copy:hover, .copy:focus-visible {
  color: var(--gold);
  border-color: var(--gold);
  outline: none;
}
.copy[data-done="1"] { color: var(--green); border-color: var(--green); }

mark {
  background: rgba(212, 165, 23, 0.22);
  color: inherit;
  border-radius: 2px;
  padding: 0 1px;
}

/* ------------------------------------------------------- empty / show more */

.empty {
  margin: 28px 0;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--dim);
  font-size: 14.5px;
}
.empty-title { display: block; color: var(--white); font-weight: 700; margin-bottom: 6px; }
.empty b { color: var(--gold); font-weight: 700; }

.more-wrap { margin: 16px 0 4px; text-align: center; }
.more-note {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--dim);
}
.more {
  height: 44px;
  padding: 0 20px;
  background: transparent;
  border: 1px solid var(--gold);
  border-radius: 10px;
  color: var(--gold);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.more:hover, .more:focus-visible { background: rgba(212, 165, 23, 0.1); outline: none; }

/* ------------------------------------------------------------------ footer */

.foot {
  margin-top: 32px;
  padding: 22px 0 40px;
  border-top: 1px solid var(--border);
}
.disclaimer {
  margin: 0;
  max-width: 62ch;
  color: var(--dim);
  font-size: 13px;
}
.meta {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--border);
}
.meta .dot { margin: 0 8px; }

/* --------------------------------------------------------- the city sheet */

body.sheet-open { overflow: hidden; }

.sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  /* visibility rather than display, so the panel can slide out on the way
     closed - and so it leaves the accessibility tree while it is shut. */
  visibility: hidden;
  transition: visibility 0s linear 0.24s;
}
.sheet.is-open {
  visibility: visible;
  transition-delay: 0s;
}

.sheet-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: opacity 0.24s ease;
}
.sheet.is-open .sheet-scrim { opacity: 1; }

.sheet-panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-width: var(--wrap);
  margin: 0 auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: 18px 18px 0 0;
  padding: 8px 0 max(12px, env(safe-area-inset-bottom));
  transform: translateY(100%);
  /* Decelerating, no overshoot: a sheet that bounces reads as a toy, and this
     one is opened one-handed in a car. */
  transition: transform 0.24s cubic-bezier(0.32, 0.72, 0, 1);
}
.sheet.is-open .sheet-panel { transform: translateY(0); }

.sheet-grab {
  width: 38px; height: 4px;
  margin: 0 auto 6px;
  border-radius: 2px;
  background: var(--border);
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 14px 10px;
  border-bottom: 1px solid var(--border);
}
.sheet-title {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.sheet-done {
  min-height: 40px;
  padding: 0 16px;
  background: transparent;
  border: 1px solid var(--gold);
  border-radius: 10px;
  color: var(--gold);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.sheet-done:hover, .sheet-done:focus-visible {
  background: rgba(212, 165, 23, 0.12);
  outline: none;
}

/* ------------------------------------------------------------ the wheel */

/* An iOS-style drum. The browser does the scrolling, the momentum and the
   snap; the only thing done by hand is the 3D, and that is one transform per
   row. --rows must stay odd so there is a middle one to select. */
.picker {
  --item-h: 44px;
  --rows: 5;
  position: relative;
  height: calc(var(--item-h) * var(--rows));
}

.picker-scroll {
  height: 100%;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  /* Without this, flicking past the last city scrolls the page behind the
     scrim on iOS. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.picker-scroll::-webkit-scrollbar { display: none; }
.picker-scroll:focus { outline: none; }

/* The wheel takes arrow keys, so it has to show that it has focus - but the
   ring belongs on the wrapper, not on the scroller. Drawn on the scroller it
   is painted underneath the two edge fades, which eat the top and bottom of
   it and leave a stray vertical line down one side. */
.picker.is-focused {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 12px;
}

/* Half the wheel above the first city and below the last, so either can reach
   the middle. Real elements rather than padding: a scroll container's bottom
   padding is dropped by more browsers than not. */
.picker-spacer {
  height: calc((var(--rows) - 1) / 2 * var(--item-h));
}

.picker-item {
  height: var(--item-h);
  scroll-snap-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  font-size: 17px;
  font-weight: 600;
  color: var(--white);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  will-change: transform, opacity;
  -webkit-tap-highlight-color: transparent;
}
.picker-item.is-selected {
  color: var(--gold);
  font-weight: 700;
}

/* The slot. Sits under the rows and takes no pointer events, so a tap on a
   city still reaches the city. */
.picker-band {
  position: absolute;
  left: 10px; right: 10px;
  top: calc((var(--rows) - 1) / 2 * var(--item-h));
  height: var(--item-h);
  border-top: 1px solid rgba(212, 165, 23, 0.45);
  border-bottom: 1px solid rgba(212, 165, 23, 0.45);
  background: rgba(212, 165, 23, 0.07);
  pointer-events: none;
}

/* Rows fade into the panel at the top and bottom of the drum rather than being
   clipped flat, which is most of what sells the curve. */
.picker-fade {
  position: absolute;
  left: 0; right: 0;
  height: calc(var(--item-h) * 1.6);
  pointer-events: none;
}
.picker-fade-top {
  top: 0;
  background: linear-gradient(to bottom, var(--card) 12%, rgba(19, 29, 48, 0));
}
.picker-fade-bottom {
  bottom: 0;
  background: linear-gradient(to top, var(--card) 12%, rgba(19, 29, 48, 0));
}

/* ------------------------------------------------------------ adaptations */

@media (max-width: 480px) {
  .row { padding: 11px 12px; }
  .copy { min-width: 56px; }
  .meta .dot { margin: 0 5px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* The palette is a dark one by design - it is what the app looks like, and it
   is what an officer wants at 3am. A light-mode viewer gets the same thing
   rather than a washed-out approximation of it. */
