/*
 * The join page.
 *
 * Read on a phone, in a shack, by somebody who is also restarting a hotspot.
 * It is a single column of steps at a size that survives being glanced at, not
 * a dashboard.
 *
 * Every value here is a token from tokens.css. A raw hex value in this file is
 * a defect, per the note at the top of that file.
 */

.join-body {
  background: var(--color-background);
  color: var(--color-foreground);
  font-family: var(--font-ui);
  line-height: var(--leading-normal);
  margin: 0;
}

.join {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4) var(--space-7);
}

/* ---- Header ---------------------------------------------------------- */

.join__head {
  text-align: center;
  margin-bottom: var(--space-6);
}

.join__mark {
  width: 2.5rem;
  height: 2.5rem;
  color: var(--color-primary);
}

.join__title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  margin: var(--space-3) 0 var(--space-2);
}

.join__lede {
  color: var(--color-foreground-muted);
  font-size: var(--text-base);
  margin: 0;
}

/* ---- Notices --------------------------------------------------------- */

/* .notice moved to console.css: the sign-in page needs it too, and both
   pages already load that file. */

/* ---- Steps ----------------------------------------------------------- */

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
}

.step {
  counter-increment: step;
  position: relative;
  padding: 0 0 var(--space-6) var(--space-6);
  border-left: 1px solid var(--color-border);
}

.step:last-child {
  border-left-color: transparent;
  padding-bottom: var(--space-4);
}

/* The number sits on the rail, so the eye can find "which step am I on"
 * without reading. */
.step::before {
  content: counter(step);
  position: absolute;
  left: calc(var(--space-6) / -2 - 0.75rem);
  top: 0;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-foreground-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  display: flex;
  align-items: center;
  justify-content: center;
}

.step__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-2);
}

.step__body {
  color: var(--color-foreground-muted);
  margin: 0 0 var(--space-3);
}

.step__note {
  color: var(--color-foreground-subtle);
  font-size: var(--text-sm);
  margin: var(--space-3) 0 0;
}

.step code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-muted);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.35em;
  color: var(--color-foreground);
}

.step strong {
  color: var(--color-foreground);
  font-weight: var(--weight-semibold);
}

/* ---- Field tables ---------------------------------------------------- */

.fields {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-3) 0;
  font-size: var(--text-sm);
}

.fields th,
.fields td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  vertical-align: baseline;
}

.fields tbody tr:last-child th,
.fields tbody tr:last-child td {
  border-bottom: none;
}

.fields th[scope="row"] {
  color: var(--color-foreground-muted);
  font-weight: var(--weight-normal);
  white-space: nowrap;
}

.fields thead th {
  color: var(--color-foreground-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.fields__missing {
  color: var(--color-foreground-subtle);
  font-style: italic;
}

/* A value in a <code> box reads as "type this exactly". When there is no value
 * to give, the box has to go, or the placeholder gets typed instead. */
.field--missing {
  font-family: var(--font-ui);
  font-style: italic;
  color: var(--color-foreground-subtle);
  background: none;
  padding: 0;
}

/* Nothing can connect yet, so the steps are premature rather than unavailable.
 *
 * The first attempt dimmed them to opacity 0.45. That dropped
 * --color-foreground-muted from the 7.4:1 contrast tokens.css guarantees to
 * roughly 3.3:1, under the 4.5:1 minimum — breaking an accessibility promise
 * the design system states in a comment, in order to convey state. Opacity is
 * the wrong tool for "not yet".
 *
 * Instead the rail loses its solidity and the steps sit slightly back. Text
 * contrast is untouched. */
.steps--blocked .step {
  border-left-style: dashed;
}

.steps--blocked .step::before {
  border-style: dashed;
  color: var(--color-foreground-subtle);
}

.steps--blocked .waiting {
  border-style: dashed;
}

/* The number to dial is the one thing on this page a member must get right. */
.tg-dial {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--color-primary);
  background: none;
  padding: 0;
}

.tg-arrives {
  font-family: var(--font-mono);
  color: var(--color-foreground-subtle);
}

/* ---- Waiting for the hotspot ----------------------------------------- */

.waiting {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  margin: var(--space-3) 0;
}

.waiting__dot {
  flex: 0 0 auto;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--color-unavailable);
}

.waiting__text {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-foreground-muted);
}

.waiting[data-state="waiting"] .waiting__dot {
  background: var(--color-degraded);
  animation: waiting-pulse 2s var(--ease-out-expo) infinite;
}

/* Status is never colour alone: the text changes too, and the border carries
 * the same signal for anyone who cannot distinguish the dot. */
.waiting[data-state="found"] {
  border-color: var(--color-healthy);
}

.waiting[data-state="found"] .waiting__dot {
  background: var(--color-healthy);
}

.waiting[data-state="found"] .waiting__text {
  color: var(--color-foreground);
  font-weight: var(--weight-medium);
}

.waiting[data-state="off"] .waiting__dot {
  background: var(--color-unavailable);
}

@keyframes waiting-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  .waiting[data-state="waiting"] .waiting__dot {
    animation: none;
  }
}

/* ---- Further reading -------------------------------------------------- */

/* A section after the steps: not a step, so no number on the rail, but set in
   the same measure so it reads as part of the page rather than an appendix. */
.extra {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.extra__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-2);
}

.extra__body {
  color: var(--color-foreground-muted);
  margin: 0 0 var(--space-3);
}

.extra strong {
  color: var(--color-foreground);
  font-weight: var(--weight-semibold);
}

.extra code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-muted);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.35em;
  color: var(--color-foreground);
}

/* The format column names the setting as a radio's menu shows it. */
.fields--formats th[scope="row"] {
  color: var(--color-foreground);
  font-weight: var(--weight-semibold);
}

.fields--formats td {
  color: var(--color-foreground-muted);
}

/* The one to choose is marked by its row, not only by its tag, so the
   recommendation survives a quick glance down the table. */
.fields__recommended th,
.fields__recommended td {
  background: color-mix(in srgb, var(--color-healthy) 8%, transparent);
}

.extra__tag {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  border: 1px solid var(--color-healthy);
  border-radius: 999px;
  color: var(--color-healthy);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  vertical-align: 1px;
}

.extra__list {
  margin: var(--space-3) 0 0;
  padding-left: var(--space-5);
  color: var(--color-foreground-muted);
  font-size: var(--text-sm);
}

.extra__list li + li {
  margin-top: var(--space-2);
}

/* A section that opens: the AllStar node's settings, wanted by few readers
   of this page. Closed it is one line in the same card as the one above. */
.extra--fold {
  padding: 0;
}

.extra__summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  list-style: none;
  border-radius: var(--radius-lg);
}

.extra__summary::-webkit-details-marker {
  display: none;
}

.extra__summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.extra__summary .extra__title {
  margin: 0;
}

.extra__chevron {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--color-foreground-subtle);
  transition: transform var(--duration-fast) var(--ease-out-expo);
}

.extra--fold[open] .extra__chevron {
  transform: rotate(90deg);
}

.extra--fold > :not(summary) {
  margin-left: var(--space-5);
  margin-right: var(--space-5);
}

.extra--fold > :last-child {
  margin-bottom: var(--space-5);
}

.extra__label {
  margin: var(--space-4) 0 0;
  color: var(--color-foreground-muted);
  font-size: var(--text-sm);
}

.extra__note {
  margin: var(--space-3) 0 0;
  color: var(--color-foreground-subtle);
  font-size: var(--text-sm);
}

@media (prefers-reduced-motion: reduce) {
  .extra__chevron {
    transition: none;
  }
}

/* ---- Footer ---------------------------------------------------------- */

.join__foot {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  color: var(--color-foreground-subtle);
  font-size: var(--text-sm);
  text-align: center;
}

.join__foot p {
  margin: 0;
}

/* The talkgroup table's own modifier. It was in the markup with no rule behind
   it, which the class check found — a hook somebody added and never used.
   Given a rule rather than removed: a table of numbers reads better with the
   numeric column aligned, which is what it was presumably for. */
.fields--talkgroups td:first-child {
  font-family: var(--font-mono);
}

/* ---- Choosing whether other networks stay ----------------------------- */

/* A quarter of a club runs another network alongside this one, and the page
   used to tell all of them to turn it off. The answer changes which steps
   apply, so it is asked once, at the top, rather than assumed. */
.choice {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-3) 0;
}

.choice__option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-control);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.choice__option:hover {
  border-color: var(--color-foreground-muted);
}

.choice__option input {
  margin: 0;
  /* The control is small and the whole row is the target, which is what the
     44px minimum asks for without a 44px radio button. */
  min-width: 16px;
  min-height: 16px;
}

/* ---- The generated block --------------------------------------------- */

/* The picker and field rules live in console.css, which the join page also
   loads. They were duplicated here and only here, which is why the links page
   rendered its inputs as browser defaults. */

/* The generated-block rules live in console.css, which the links page also
   needs them for. */

/* Not styled as warnings. Every one of these is an ordinary thing to check,
   and painting four of them amber on a page a member reads once teaches them
   that amber is decoration. */
.config__warnings {
  margin: var(--space-4) 0 0;
  padding-left: var(--space-5);
  color: var(--color-foreground-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.config__warnings li {
  margin-bottom: var(--space-2);
}
