/* ==========================================================================
   ItemSpan — Components
   --------------------------------------------------------------------------
   Reusable pieces that appear on more than one page: buttons, cards, badges,
   the phone mockup, the waitlist form, the FAQ accordion, and tables.
   Page-specific styling lives in pages.css instead.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Icons
   --------------------------------------------------------------------------
   All icons come from icons.svg, referenced with <use>. They inherit their
   colour from the surrounding text via currentColor, so the markup never
   specifies a colour — set `color` on the parent instead.

   Default size is 24px; override with a width/height on the specific rule
   that needs it, or use one of the size modifiers below.
   -------------------------------------------------------------------------- */

.icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.icon-sm { width: 16px; height: 16px; }
.icon-md { width: 20px; height: 20px; }
.icon-lg { width: 32px; height: 32px; }

/* --------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------
   min-height 48px is not arbitrary — it is the minimum comfortable touch
   target. Every interactive element on the site meets it.
   -------------------------------------------------------------------------- */

.button {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border-radius: var(--radius-md);
  padding: 0 var(--space-5);
  border: 1px solid transparent;
  text-decoration: none;
  font-size: 0.95rem;
  line-height: 1;
  font-weight: 680;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}

.button:hover {
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
}

.button-primary {
  border-color: var(--evergreen);
  background: var(--evergreen);
  color: #fff;
}

.button-primary:hover {
  border-color: var(--evergreen-pressed);
  background: var(--evergreen-pressed);
  box-shadow: 0 6px 20px rgba(11, 107, 87, 0.25);
}

.button-outline {
  border: 1.5px solid var(--evergreen);
  background: transparent;
  color: var(--evergreen);
}

.button-outline:hover {
  background: var(--mist);
}

.button-large {
  min-height: 56px;
  padding-inline: var(--space-6);
  font-size: 1.02rem;
}

.button-block {
  width: 100%;
}

/* A button-shaped element that is deliberately not clickable yet — used for
   the store links that don't exist until the listings are approved. */
.button-disabled {
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #f1f4f2;
  color: var(--secondary);
  font-size: 0.86rem;
  font-weight: 620;
  cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Text link
   -------------------------------------------------------------------------- */

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  color: var(--evergreen);
  font-weight: 680;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
}

/* The arrow slides on hover — a small cue that the link goes somewhere. */
.text-link svg {
  transition: transform var(--duration-fast) var(--ease);
}

.text-link:hover svg {
  transform: translateX(3px);
}

/* --------------------------------------------------------------------------
   Badges and eyebrows
   -------------------------------------------------------------------------- */

/* Small caps label that sits above a heading to name the category. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--evergreen);
  font-size: 0.82rem;
  font-weight: 680;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Pill used for launch status. The dot pulses gently to read as "live". */
.status-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: var(--weight-semibold);
}

.status-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--evergreen);
  animation: pulse 2.4s var(--ease) infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.82); }
}

/* Highlight pill for a plan card, e.g. "Save $16 a year". */
.tag-gold {
  display: inline-flex;
  align-items: center;
  padding: 4px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: var(--ink);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--duration-base) var(--ease),
              box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease);
}

.card-hover:hover {
  border-color: var(--evergreen);
  box-shadow: var(--shadow-card);
  transform: translateY(-3px);
}

/* Round evergreen-on-mist icon chip used throughout the site. */
.icon-chip {
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--mist);
  color: var(--evergreen);
}

.icon-chip svg {
  width: 26px;
  height: 26px;
  stroke-width: 1.75;
}

.icon-chip-lg {
  width: 82px;
  height: 82px;
  flex-basis: 82px;
}

.icon-chip-lg svg {
  width: 38px;
  height: 38px;
  stroke-width: 1.65;
}

/* --------------------------------------------------------------------------
   Trust strip
   --------------------------------------------------------------------------
   Row of short factual reassurances under the hero CTAs.
   -------------------------------------------------------------------------- */

.trust-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-5) var(--space-6);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}

.trust-item {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: var(--space-3);
  align-items: start;
}

.trust-item svg {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  color: var(--evergreen);
}

.trust-item strong {
  display: block;
  font-size: 0.92rem;
  color: var(--ink);
}

.trust-item span {
  display: block;
  margin-top: 2px;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--secondary);
}

/* --------------------------------------------------------------------------
   Waitlist form
   --------------------------------------------------------------------------
   One email field plus a submit button. On wide screens they sit side by side;
   below 560px the button drops underneath at full width.
   -------------------------------------------------------------------------- */

.waitlist {
  max-width: 520px;
}

.waitlist-fields {
  display: flex;
  gap: var(--space-3);
  align-items: stretch;
}

.waitlist input[type="email"] {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 56px;
  padding: 0 var(--space-4);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--ink);
  font-size: 1rem;
  transition: border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}

.waitlist input[type="email"]::placeholder {
  color: var(--secondary);
  opacity: 0.75;
}

.waitlist input[type="email"]:hover {
  border-color: var(--secondary);
}

.waitlist input[type="email"]:focus {
  border-color: var(--evergreen);
  box-shadow: 0 0 0 3px rgba(11, 107, 87, 0.12);
}

.waitlist input[type="email"][aria-invalid="true"] {
  border-color: var(--warning);
}

/* Spam trap. Bots fill in every field they find; humans never see this one.
   Hidden with position rather than display:none because some bots skip fields
   that are display:none. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.waitlist-note {
  margin-top: var(--space-3);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--secondary);
}

/* Status messages, revealed by js/site.js after a submit attempt. */
.form-message {
  display: none;
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  line-height: 1.5;
}

.form-message.is-visible {
  display: block;
}

.form-message-success {
  border: 1px solid var(--evergreen);
  background: var(--evergreen-tint);
  color: var(--evergreen-pressed);
  font-weight: var(--weight-semibold);
}

.form-message-error {
  border: 1px solid var(--warning);
  background: #fff3d6;
  color: #5b3a00;
}

@media (max-width: 560px) {
  .waitlist-fields {
    flex-direction: column;
  }

  .waitlist .button {
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   FAQ accordion
   --------------------------------------------------------------------------
   Built on <button aria-expanded> rather than <details> so the open/closed
   state can be animated and controlled consistently across browsers.
   js/site.js toggles both aria-expanded and the .is-open class.
   -------------------------------------------------------------------------- */

.faq-list {
  border-top: 1px solid var(--gold);
}

.faq-item {
  border-bottom: 1px solid var(--gold);
  transition: border-color var(--duration-fast) var(--ease);
}

/* The heading level varies by page — h2 on the Support page (directly under
   its h1), h3 on the home page (under a section h2). Match any level so the
   accordion looks identical wherever it is used and the document outline stays
   correct. */
.faq-item :is(h2, h3, h4) {
  font-family: var(--font-body);
  font-size: 1.05rem;
  line-height: 1.35;
  letter-spacing: -0.01em;
  font-weight: var(--weight-semibold);
  margin: 0;
}

.faq-question {
  width: 100%;
  min-height: 60px;
  padding: var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  background: transparent;
  color: var(--ink);
  text-align: left;
  font-weight: 610;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}

.faq-question:hover {
  background: var(--mist);
}

.faq-question svg {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  color: var(--evergreen);
  transition: transform var(--duration-base) var(--ease);
}

.faq-question[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* Collapsed by default. js/site.js measures the answer and sets an explicit
   max-height in pixels to animate, then clears it to `none` once the
   transition finishes, so a later reflow (window resize, font swap, zoom)
   can never clip the text.

   The trendier way to do this is `grid-template-rows: 0fr -> 1fr`, which needs
   no measuring. It is used here instead because max-height animation works in
   every browser, while fr-unit interpolation needs Chrome 107+, Safari 16+, or
   Firefox 129+. The cost is the JS measurement above; the benefit is that the
   answers still open on an older phone. */
.faq-answer {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height var(--duration-base) var(--ease),
              opacity var(--duration-base) var(--ease);
}

.faq-item.is-open .faq-answer {
  opacity: 1;
}

/* Without JavaScript nothing can measure or toggle, so every answer is shown
   in full. The page becomes a plain list of questions and answers. */
.no-js .faq-answer {
  max-height: none;
  opacity: 1;
}

.no-js .faq-question svg {
  display: none;
}

.faq-answer p {
  padding: 0 48px var(--space-5) var(--space-3);
  font-size: 0.94rem;
  line-height: 1.65;
}

.faq-item.is-open {
  border: 1.5px solid var(--evergreen);
  border-radius: var(--radius-md);
  margin-top: -1px;
}

.faq-item.is-open + .faq-item {
  border-top: 0;
}

/* --------------------------------------------------------------------------
   Comparison table
   --------------------------------------------------------------------------
   On narrow screens the table reflows into stacked rows. Each cell carries a
   data-label attribute that becomes its heading via the ::before below, so no
   markup is duplicated for mobile.
   -------------------------------------------------------------------------- */

.table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.comparison-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.comparison-table th,
.comparison-table td {
  padding: var(--space-3) var(--space-4);
  border-right: 1px solid #dbe4e1;
  border-bottom: 1px solid #dbe4e1;
}

.comparison-table tr:last-child > * {
  border-bottom: 0;
}

.comparison-table tr > *:last-child {
  border-right: 0;
}

.comparison-table thead {
  background: var(--mist);
}

.comparison-table th {
  text-align: left;
  font-weight: 620;
  color: var(--ink);
}

.comparison-table thead th:not(:first-child),
.comparison-table td {
  width: 28%;
  text-align: center;
}

.comparison-table tbody tr:hover {
  background: rgba(234, 244, 240, 0.45);
}

/* Included / not-included marks. */
.mark-yes {
  width: 20px;
  height: 20px;
  margin: auto;
  padding: 2px;
  border: 1.5px solid var(--evergreen);
  border-radius: 50%;
  color: var(--evergreen);
}

.mark-no {
  color: var(--secondary);
}

@media (max-width: 720px) {
  .comparison-table thead {
    /* Visually hidden, still announced to screen readers. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }

  .comparison-table tr {
    display: block;
    border-bottom: 1px solid #dbe4e1;
  }

  .comparison-table tr:last-child {
    border-bottom: 0;
  }

  .comparison-table th[scope="row"] {
    display: block;
    background: var(--mist);
    border-right: 0;
    font-weight: 650;
  }

  .comparison-table td {
    width: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-align: right;
    border-right: 0;
  }

  .comparison-table td::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--secondary);
  }

  .mark-yes {
    margin: 0;
  }
}

/* --------------------------------------------------------------------------
   Phone mockup
   --------------------------------------------------------------------------
   An illustration of the app drawn entirely in HTML and CSS — there are no
   image assets involved. To replace it with a real screenshot later, put an
   <img> inside .phone-screen and delete that panel's children.
   -------------------------------------------------------------------------- */

.phone-wrap {
  position: relative;
  z-index: 3;
  width: min(100%, 370px);
  justify-self: center;
}

.phone-shell {
  position: relative;
  min-height: 610px;
  padding: 14px 11px 23px;
  border: 4px solid #182220;
  border-radius: var(--radius-phone);
  background: #080b0a;
  box-shadow: var(--shadow-phone);
  overflow: hidden;
}

/* Status bar with the notch/island. */
.phone-top {
  position: relative;
  height: 37px;
  padding: 7px 12px;
  border-radius: 37px 37px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  background: #fff;
  color: #0c1514;
  font-size: 0.7rem;
  font-weight: 700;
}

.phone-top.is-dark {
  background: var(--evergreen-pressed);
  color: #fff;
}

.phone-island {
  position: absolute;
  width: 82px;
  height: 23px;
  top: 5px;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 20px;
  background: #020303;
}

.phone-screen {
  min-height: 525px;
  padding: 10px 11px 17px;
  background: #f8faf8;
  color: var(--ink);
}

/* The home indicator bar at the bottom of the device. */
.phone-home {
  position: absolute;
  bottom: 8px;
  left: 50%;
  width: 112px;
  height: 4px;
  border-radius: 4px;
  background: #fff;
  transform: translateX(-50%);
}

/* --- Contents of the home-screen mockup --- */

.preview-title-row,
.preview-panel-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.preview-title-row {
  padding: 2px 2px 10px;
  font-family: var(--font-display);
  font-size: 1.15rem;
}

.preview-search {
  height: 36px;
  margin-bottom: 10px;
  padding: 0 10px;
  border: 1px solid #d4dedb;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  gap: 7px;
  background: #fff;
  color: #65736f;
  font-size: 0.69rem;
}

.preview-search svg {
  width: 14px;
  height: 14px;
}

.preview-panel {
  margin-top: 10px;
  border: 1px solid #d9e1de;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 3px 8px var(--ink-a06);
  overflow: hidden;
}

.preview-panel-title {
  padding: 11px 10px 8px;
  font-size: 0.8rem;
}

.preview-panel-title span {
  color: var(--evergreen);
  font-size: 0.62rem;
}

.preview-row {
  min-height: 65px;
  padding: 8px 9px;
  border-top: 1px solid #edf1ef;
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 9px;
}

.preview-icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: var(--mist);
  color: var(--evergreen);
}

.preview-icon svg {
  width: 20px;
  height: 20px;
}

.preview-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.72rem;
}

.preview-label small {
  color: var(--evergreen);
  font-size: 0.59rem;
}

.preview-chevron {
  width: 16px;
  height: 16px;
  color: var(--secondary);
}

.preview-records {
  padding-bottom: 5px;
}

.record-row {
  min-height: 40px;
  padding: 5px 10px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-2);
  align-items: center;
  font-size: 0.68rem;
}

.record-dot {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--evergreen);
  border-radius: 50%;
}

.record-row small {
  color: var(--secondary);
  font-size: 0.54rem;
}

/* --- Contents of the product-record mockup (Features page) --- */

.feature-phone {
  width: 305px;
}

.feature-phone .phone-shell {
  min-height: 585px;
}

.product-bar {
  height: 46px;
  padding: 0 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--evergreen-pressed);
  color: #fff;
  font-size: 0.72rem;
}

.product-screen {
  min-height: 475px;
}

.product-summary {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 8px 0 14px;
}

.product-placeholder {
  width: 50px;
  height: 50px;
  display: grid;
  place-items: center;
  background: var(--mist);
  border-radius: 9px;
  color: var(--evergreen);
}

.product-summary > span:last-child {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.72rem;
}

.product-summary small {
  color: var(--evergreen);
}

.preview-field {
  margin: 9px 0;
  font-size: 0.59rem;
}

.preview-field > strong {
  display: block;
  margin-bottom: 5px;
}

.field-box,
.code-line {
  min-height: 34px;
  border: 1px solid #ced9d5;
  background: #fff;
  display: flex;
  align-items: center;
}

.field-box {
  justify-content: space-between;
  padding: 0 9px;
  border-radius: 6px;
}

.code-line {
  padding: 0 7px;
  gap: var(--space-2);
}

.code-line:first-of-type {
  border-radius: 6px 6px 0 0;
}

.code-line:last-child {
  border-top: 0;
  border-radius: 0 0 6px 6px;
}

.code-line small {
  margin-left: auto;
  color: var(--secondary);
}

.preview-caption {
  max-width: 330px;
  margin: var(--space-5) auto 0;
  font-size: 0.86rem;
  color: var(--ink);
  text-align: center;
}

/* --------------------------------------------------------------------------
   The gold "span" line
   --------------------------------------------------------------------------
   The brand mark is a continuous path that spans three levels. This is the
   same gesture drawn at page scale behind the hero: a horizontal rule with a
   curve entering at one end and leaving at the other. Purely decorative.
   -------------------------------------------------------------------------- */

.span-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 58px;
  height: 74px;
  border-bottom: 4px solid var(--gold);
  pointer-events: none;
}

.span-line::before,
.span-line::after {
  content: "";
  position: absolute;
  bottom: -4px;
  width: 90px;
  height: 42px;
  border: 4px solid var(--gold);
}

.span-line::before {
  left: -20px;
  border-right: 0;
  border-bottom: 0;
  border-radius: 0 42px 0 0;
  transform: translateY(42px);
}

.span-line::after {
  right: -20px;
  border-left: 0;
  border-top: 0;
  border-radius: 0 0 0 42px;
  transform: translateY(-42px);
}

/* --------------------------------------------------------------------------
   Scroll reveal
   --------------------------------------------------------------------------
   Elements marked .reveal start slightly lowered and transparent. js/site.js
   uses an IntersectionObserver to add .is-visible as they enter the viewport.

   If JavaScript fails or is disabled, the .no-js rule at the bottom makes
   everything visible immediately — the content is never dependent on JS.
   -------------------------------------------------------------------------- */

/* Note the `.js-reveal` prefix. Content is only ever hidden once site.js has
   confirmed it can observe and un-hide it again — the class is added at the
   moment observation starts, not on page load. If the script is blocked, fails
   to parse, or throws before that point, none of these rules apply and every
   section simply renders. Hiding content by default and relying on JS to bring
   it back is how pages end up blank. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--duration-slow) var(--ease),
              transform var(--duration-slow) var(--ease);
}

.js-reveal .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger children so a row of cards arrives one after another rather than
   all at once. */
.reveal-delay-1 { transition-delay: 0.08s; }
.reveal-delay-2 { transition-delay: 0.16s; }
.reveal-delay-3 { transition-delay: 0.24s; }

/* Belt and braces: even if .js-reveal were somehow applied without JS. */
.no-js .reveal {
  opacity: 1 !important;
  transform: none !important;
}
