html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
  position: relative;
  min-height: 100%;
}

body {
  margin-bottom: 60px;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}
/* Password show/hide toggle, injected by site.js.
   Muted by default so it reads as an affordance rather than an action, and only takes on
   colour once the password is actually visible. */
.password-reveal {
  color: #6c757d;
  border-color: var(--bs-border-color);
}

.password-reveal:hover {
  color: #212529;
}

.password-reveal[aria-pressed="true"] {
  color: #0d6efd;
}

/* The validation message follows the input group rather than sitting inside it. */
.input-group + .text-danger {
  display: block;
}

/* ---------------------------------------------------------------------------------------
   Space sidebar and page tree
   --------------------------------------------------------------------------------------- */
.space-sidebar {
  background: #f8f9fa;
  border: 1px solid #dfe1e6;
  border-radius: 8px;
  padding: 1rem;
}

@media (min-width: 992px) {
  .space-sidebar {
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
  }
}

.tree-link {
  color: #42526e;
  font-size: 0.9rem;
  line-height: 1.35;
}

.tree-link:hover {
  background: #ebecf0;
  color: #091e42;
}

/* The current page, so people can see where they are in a deep tree. */
.tree-link.active {
  background: #e6effc;
  color: #0052cc;
  font-weight: 600;
}

.page-content {
  line-height: 1.6;
}

/* Sidebar collapse control. The header stays visible when the tree is hidden, so there is
   always something to click to bring it back. */
.space-sidebar-toggle {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: .4rem;
  width: 100%;
  text-align: left;
}

.space-sidebar-toggle:hover {
  color: #0052cc;
}

.toggle-caret {
  font-size: .8em;
  color: #6b778c;
}

/* A sticky sidebar that is collapsed should not still reserve the full column height. */
.space-sidebar:has(.space-sidebar-body[hidden]) {
  max-height: none;
}

/* ---------------------------------------------------------------------------------------
   Rich page content (sanitised HTML from the editor)
   --------------------------------------------------------------------------------------- */
.page-content img { max-width: 100%; height: auto; }

.page-content pre,
.page-content .ql-syntax,
.page-content .ql-code-block-container {
  background: #f4f5f7;
  padding: .75rem 1rem;
  border-radius: 4px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em;
}

.page-content blockquote {
  margin: 1rem 0;
  padding-left: 1rem;
  border-left: 3px solid #dfe1e6;
  color: #5e6c84;
}

.page-content table { border-collapse: collapse; margin: 1rem 0; }
.page-content th,
.page-content td { border: 1px solid #dfe1e6; padding: .35rem .6rem; }

/* Quill's alignment and indent classes, which the sanitiser allows through. */
.page-content .ql-align-center  { text-align: center; }
.page-content .ql-align-right   { text-align: right; }
.page-content .ql-align-justify { text-align: justify; }
.page-content .ql-indent-1 { padding-left: 3em; }
.page-content .ql-indent-2 { padding-left: 6em; }
.page-content .ql-indent-3 { padding-left: 9em; }
.page-content .ql-indent-4 { padding-left: 12em; }

/* The editor itself: give it a workable height rather than collapsing to one line. */
#editor { min-height: 24rem; background: #fff; }
#editor .ql-editor { min-height: 24rem; font-size: 1rem; }

/* ---------------------------------------------------------------------------------------
   Version comparison
   --------------------------------------------------------------------------------------- */
.diff-table td {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .85rem;
  white-space: pre-wrap;
  word-break: break-word;
  vertical-align: top;
}

.diff-inserted { background: #e3fcef; }
.diff-deleted  { background: #ffebe6; }
.diff-modified { background: #fffae6; }
.diff-blank    { background: #f4f5f7; }

/* ---------------------------------------------------------------------------------------
   Comments
   --------------------------------------------------------------------------------------- */
.comment {
  padding: .5rem .75rem;
  border-left: 2px solid #dfe1e6;
  margin-bottom: .5rem;
}

.comment-body {
  font-size: .95rem;
}

.comment-body p:last-child { margin-bottom: 0; }

.comment-thread { max-width: 760px; }

/* ---------------------------------------------------------------------------------------
   Who did it
   ---------------------------------------------------------------------------------------
   The actor column in the Activity log, the author of a note on a user's Comments tab, and
   the address shown under a user's name. All three answer "who", and all three read better
   for being visually unlike the prose around them.

   Courier and red, deliberately: it is the treatment the same column had before, it stands
   out down a long table of near-identical rows, and it is not a link colour -- nothing here
   is clickable.

   Declared here rather than left to Bootstrap's <code> styling because these are names and
   addresses, not code, and a <span> carrying its own class says so.
   --------------------------------------------------------------------------------------- */
.audit-actor {
  font-family: "Courier New", Courier, ui-monospace, monospace;
  color: #c9252d;
  font-size: .875rem;
  word-break: break-word;
}

/* Dark mode needs a lighter red: #c9252d against a near-black background is barely legible
   and fails contrast. This is the same hue, lifted. */
:root[data-mode="dark"] .audit-actor {
  color: #ff8a86;
}

/* ---------------------------------------------------------------------------------------
   Tab panes that are not direct children of .tab-content
   ---------------------------------------------------------------------------------------
   Bootstrap hides inactive panes with

       .tab-content > .tab-pane { display: none; }

   -- a DIRECT child selector. On the user record the editable panes sit inside the <form>
   that saves them, so they are grandchildren of .tab-content and that rule never matches.
   Every pane then renders at once, and the inactive ones, being .fade without .show, are
   merely transparent rather than absent: invisible, full height, and stacked. The symptom
   is a tab that opens with a screenful of blank space above and below its content.

   Wrapping each pane in its own form instead would mean either nested forms (invalid) or
   scattering the HTML5 form= attribute across every input -- which also puts those inputs
   out of reach of jquery-validation, since it finds fields by walking the form's subtree.
   So the DOM stays as it is and the selector is relaxed to a descendant one.

   Scoped to .tabs-flush rather than applied globally, because overriding a framework rule
   everywhere to fix one page is how a stylesheet becomes impossible to reason about.
   --------------------------------------------------------------------------------------- */
.tabs-flush .tab-pane { display: none; }
.tabs-flush .tab-pane.active { display: block; }

/* The first heading or paragraph in a pane must not push the content down: the tab strip
   above it is already the separation. */
.tabs-flush .tab-pane > :first-child { margin-top: 0; }

/* ---------------------------------------------------------------------------------------
   The summary band on a record
   ---------------------------------------------------------------------------------------
   The identifying facts about the thing you are looking at -- the address, when it was
   created, when it was last used -- set in a band the full width of the panel below it, so
   it reads as a header for the whole record rather than as a stray line of small print.

   Its own tokens rather than Bootstrap's bg-body-secondary, because that resolves against
   the framework's theme and this page has two of its own: the tint the reader chose, and
   dark mode. A grey that ignores both is a grey that is wrong half the time.
   --------------------------------------------------------------------------------------- */
.record-summary {
  background: #f1f2f4;
  border: 1px solid #dfe1e6;
  border-radius: .25rem;
  padding: .5rem .75rem;
  margin-bottom: 1rem;
  font-size: .875rem;
  color: #5e6c84;
}

.record-summary .audit-actor { font-size: .875rem; }

:root[data-mode="dark"] .record-summary {
  background: #1b1f27;
  border-color: #2c3340;
  color: #9aa5b1;
}

/* ---------------------------------------------------------------------------------------
   The comment log on a user record
   ---------------------------------------------------------------------------------------
   One comment per row, kept as flat as the content allows: the author and the timestamp sit
   on the same line as the start of the note, and the note itself wraps underneath only when
   it genuinely needs to.

   white-space: pre-wrap is what supports a multi-line comment -- somebody pasting three
   lines of a telephone conversation gets three lines back, rather than one run-on paragraph
   -- while a one-line comment still occupies one line.
   --------------------------------------------------------------------------------------- */
.comment-log-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .25rem .75rem;
  padding: .4rem .75rem;
}

.comment-log-meta {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  flex: 0 0 auto;
}

.comment-log-body {
  flex: 1 1 20rem;
  min-width: 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---------------------------------------------------------------------------------------
   What the inquirer said on the form
   ---------------------------------------------------------------------------------------
   Tinted pink so this card reads as a different KIND of thing from the ones around it: it is
   what somebody typed into the public form, verbatim, and it cannot be edited. The cards
   above it are the club's own record and can. Making the two look alike invites somebody to
   try to correct the one that is evidence.

   A tint rather than a border, because the distinction is about the whole block, not its
   edge -- and the dark-mode value is a desaturated plum rather than the same pink dimmed,
   which at these lightnesses reads as brown.
   --------------------------------------------------------------------------------------- */
.form-answers {
  /* A note lying on the page rather than a panel set into it: no border, a soft drop
     shadow, and square corners. Yellow with black text, like the pad it is imitating --
     and black rather than a tinted dark, because the whole point of a note is that it is
     the most legible thing on the page. */
  background: #fdf6c9;
  color: #000;
  border: none;
  border-radius: 0;
  box-shadow: 2px 3px 6px rgba(9, 30, 66, .25);

  /* Barely off square. Enough to say "stuck on" and not enough to be annoying to read;
     straightened on hover so the text is upright while somebody is reading it. */
  transform: rotate(-.5deg);
  transition: transform .15s ease;
}

.form-answers:hover { transform: rotate(0deg); }

/* Everything inside is black. Bootstrap's muted greys are tuned for a white ground and go
   muddy on yellow, and .text-muted in particular carries !important. */
.form-answers,
.form-answers .card-title,
.form-answers dt,
.form-answers dd,
.form-answers p,
.form-answers .text-muted {
  color: #000 !important;
}

/* The questions read as labels without needing a colour of their own. */
.form-answers dt { font-weight: 400; opacity: .72; }
.form-answers dd { font-weight: 600; }

/* Dark mode keeps it yellow. The point of the colour is that this block is a different kind
   of thing, and that has to survive the theme -- a note that turns grey at night is just a
   card again. Slightly deeper so it does not glare. */
:root[data-mode="dark"] .form-answers {
  background: #efe3a8;
  box-shadow: 2px 3px 8px rgba(0, 0, 0, .5);
}

/* ---------------------------------------------------------------------------------------
   Status badges and the Statistics boxes
   ---------------------------------------------------------------------------------------
   Driven by MembershipStatuses.Colour, which holds a name -- green, red, grey -- rather than
   a class. The mapping from name to appearance lives here, so restyling is a stylesheet
   change and recolouring a status is a database change, and neither needs the other.

   Every pair is chosen for contrast against its own background rather than inherited from
   Bootstrap's contextual colours, several of which fail against white at small sizes.
   --------------------------------------------------------------------------------------- */
.status-badge {
  font-weight: 600;
  border: 1px solid transparent;
}

.status-green   { background: #1f7a3d; color: #fff; }
.status-red     { background: #c0392b; color: #fff; }
.status-amber   { background: #b06f00; color: #fff; }
.status-blue    { background: #1f5fa8; color: #fff; }
.status-grey    { background: #6b7280; color: #fff; }
.status-neutral { background: #e4e6ea; color: #2b2f36; border-color: #c9ced6; }

:root[data-mode="dark"] .status-green   { background: #2e9c53; }
:root[data-mode="dark"] .status-red     { background: #d75043; }
:root[data-mode="dark"] .status-amber   { background: #c98a17; }
:root[data-mode="dark"] .status-blue    { background: #3a7fcc; }
:root[data-mode="dark"] .status-grey    { background: #7c8794; }
:root[data-mode="dark"] .status-neutral { background: #2c3340; color: #dfe3ea; border-color: #3c4553; }

/* The summary boxes on the Statistics tab, tinted to agree with the badges. A wash rather
   than the full colour: a row of saturated boxes competes with the numbers on them. */
.stat-green   { background: #e6f4ea; border-color: #a8d5b8; }
.stat-red     { background: #fdecea; border-color: #f0b8b1; }
.stat-amber   { background: #fdf3e2; border-color: #e8cf9e; }
.stat-blue    { background: #e9f1fb; border-color: #b3ceec; }
.stat-grey    { background: #f1f2f4; border-color: #d3d7dd; }

:root[data-mode="dark"] .stat-green   { background: #16301f; border-color: #2c5c3b; }
:root[data-mode="dark"] .stat-red     { background: #351a17; border-color: #6b332c; }
:root[data-mode="dark"] .stat-amber   { background: #33280f; border-color: #6b5420; }
:root[data-mode="dark"] .stat-blue    { background: #16232f; border-color: #2d4a66; }
:root[data-mode="dark"] .stat-grey    { background: #22262d; border-color: #3a4049; }

/* ---------------------------------------------------------------------------------------
   The membership activity log
   ---------------------------------------------------------------------------------------
   One entry per row wherever the content allows it: the type, the summary, who and when all
   sit on one line, with the body opening underneath only when somebody asks for it. The log
   is scanned far more often than it is read, and a scannable log is a compact one.
   --------------------------------------------------------------------------------------- */
.activity-item {
  padding: .4rem .75rem;
}

.activity-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .25rem .5rem;
}

.activity-summary {
  flex: 1 1 12rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.activity-meta {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: .5rem;
  white-space: nowrap;
}

.activity-detail {
  white-space: pre-wrap;
  word-break: break-word;
  margin-top: .25rem;
}

/* The disclosure arrow on its own line wastes a row per entry. */
.activity-item details > summary {
  display: inline;
  cursor: pointer;
}

/* ---------------------------------------------------------------------------------------
   Pipeline status toggles
   ---------------------------------------------------------------------------------------
   The tick or cross in front of the label carries the state as well as the colour does, so
   the control still works for a reader who cannot separate the green from the grey.
   --------------------------------------------------------------------------------------- */
.status-toggle { text-transform: none; }

.status-toggle span[aria-hidden] {
  font-weight: 700;
  margin-right: .15rem;
}


/* ---------------------------------------------------------------------------------------
   The orange button
   ---------------------------------------------------------------------------------------
   The club's action colour: #FFCC66 with black text. Used for signing in and for opening a
   module -- the things a person came to the page to do.

   Black text rather than white, and not negotiable: #FFCC66 is a light colour, and white on
   it fails contrast badly enough to be unreadable in sunlight on a phone. Black on it is
   comfortably past the threshold.

   The hover and active shades are darker rather than lighter, so the button still reads as
   pressed on a screen where the ambient light has washed the difference out.
   --------------------------------------------------------------------------------------- */
.btn-orange {
  background-color: #ffcc66;
  border-color: #e6b84d;
  color: #000;
  font-weight: 600;
}

.btn-orange:hover,
.btn-orange:focus {
  background-color: #f5bd47;
  border-color: #d9a733;
  color: #000;
}

.btn-orange:active,
.btn-orange.active {
  background-color: #e6ae38;
  border-color: #c9971f;
  color: #000;
}

.btn-orange:focus-visible {
  outline: 2px solid #7a5a00;
  outline-offset: 2px;
  box-shadow: none;
}

.btn-orange:disabled,
.btn-orange.disabled {
  background-color: #ffe4ab;
  border-color: #ffe4ab;
  color: #6b6b6b;
}

/* Dark mode leaves the fill alone. It is a brand colour and a call to action -- dimming it
   would make the one thing the page wants you to press the quietest thing on it. */

/* ---------------------------------------------------------------------------------------
   Email addresses in the membership pipeline
   ---------------------------------------------------------------------------------------
   Blue, because an address is a thing you act on -- you write to it -- and it should look
   different from the telephone number sitting under it. Not a link: there is nothing to
   click, and styling non-links as links teaches people to distrust the ones that are.
   --------------------------------------------------------------------------------------- */
.email-text {
  color: #1f5fa8;
  word-break: break-word;
}

:root[data-mode="dark"] .email-text { color: #7fb3f0; }
