/* Abstract submission form. Linked only from abstracts.html. */

/* Local tokens for this page's controls, derived from the brand ones: one height,
   one radius, and the radius is .btn's. */
main {
  --control-height: var(--space-7);
  --control-radius: var(--radius-md);
}

/* Several controls below set display, which beats the UA's [hidden]. !important is
   what makes the attribute authoritative again; the scope keeps it off the shared
   header, nav and footer. */
main [hidden] { display: none !important; }

/* Status the JS shows: closed, the form or the submission could not be loaded, the
   PDF did not upload. Each changes what the reader can do now, so it takes the
   site's "this matters" block, the same declarations as .callout in info.css.
   What is merely pending, a fact the client has not sent, keeps the muted italic. */
.abstract-notice {
  max-width: var(--max-width-prose);
  padding: var(--space-5) var(--space-6);
  background-color: var(--color-primary);
  color: var(--color-on-dark);
  border-radius: var(--radius-lg);
}
.abstract-notice a { color: var(--color-on-dark); }
.abstract-notice a:hover { color: var(--color-on-dark-muted); }

.abstract-form { max-width: var(--max-width-prose); }
.abstract-form > * + * { margin-top: var(--space-6); }

.abstract-fieldset {
  margin: 0;
  padding: var(--space-5);
  min-width: 0;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.abstract-fieldset > legend {
  padding: 0 var(--space-2);
  font-family: var(--font-display);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-md);
  color: var(--color-primary);
}

.abstract-field + .abstract-field,
.abstract-field + .abstract-choice,
.abstract-choice + .abstract-field,
.abstract-consent + .abstract-field,
.abstract-hint + .abstract-field { margin-top: var(--space-5); }

.abstract-field label,
.abstract-choice > legend {
  display: block;
  margin-bottom: var(--space-2);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.abstract-field input,
.abstract-field select,
.abstract-field textarea,
.markup-editor,
.author__field input {
  display: block;
  width: 100%;
  min-width: 0;
  padding: var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-steel);
  border-radius: var(--control-radius);
}
.abstract-field input,
.abstract-field select,
.author__field input {
  height: var(--control-height);
  padding-block: 0;
}
.abstract-field textarea { resize: vertical; line-height: var(--line-base); }
/* Written on the rendered text; sized like the textareas it replaced, two
   lines for the title and fourteen for the abstract, and it grows with what is typed. */
.markup-editor {
  min-height: calc(2lh + 2 * var(--space-3));
  line-height: var(--line-base);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  cursor: text;
}
.markup-editor[aria-multiline="true"] { min-height: calc(14lh + 2 * var(--space-3)); }

.abstract-form [aria-invalid="true"] {
  border-width: 2px;
  border-color: var(--color-danger);
  background-color: var(--color-danger-soft);
  box-shadow: inset 4px 0 0 var(--color-danger);
}

.abstract-hint { margin: var(--space-2) 0 0; font-size: var(--font-size-sm); color: var(--color-muted); }
.abstract-count[data-over="true"] { color: var(--color-danger); font-weight: var(--font-weight-bold); }

.field-error {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger);
}

.abstract-choice { margin: 0; padding: 0; border: 0; min-width: 0; }
.abstract-choice__option {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-right: var(--space-6);
  min-height: 44px;
  cursor: pointer;
}
.abstract-choice__option input,
.author__presenter input,
.abstract-consent input { width: 1.25rem; height: 1.25rem; margin: 0; accent-color: var(--color-accent); }

/* Authors. A numbered row per author: the number is the print order, and
   on wide screens the three fields sit on one line under labels shown once, on the
   first row, so the list reads as a table. The controls are quiet icons; the one thing
   that stands out is who presents, in the site's navy. */
.author-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; }
.author {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  column-gap: var(--space-3);
  row-gap: var(--space-2);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
  margin: 0;
}
.author:first-child { padding-top: 0; }
.author__num {
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  margin-top: 1.6rem;
  border-radius: var(--radius-pill);
  background-color: var(--color-surface-sunken);
  color: var(--color-primary);
  font-family: var(--font-display);
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}
.author[data-presenter] .author__num {
  background-color: var(--color-primary);
  color: var(--color-on-dark);
}
.author__fields,
.author__role { grid-column: 2; }
.author__fields { display: grid; gap: var(--space-2); grid-template-columns: minmax(0, 1fr); }
.author__label,
.author__email label {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
}
.author__label-hint { font-weight: var(--font-weight-regular); color: var(--color-muted); }
.author__actions { display: flex; gap: var(--space-1); margin-left: auto; }
.author__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--control-radius);
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
}
.author__icon:hover:not(:disabled) { background-color: var(--color-surface-sunken); color: var(--color-primary); }
.author__icon--remove:hover:not(:disabled) { color: var(--color-danger); }
.author__icon:disabled { opacity: 0.35; cursor: default; }
.author__role {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3) var(--space-4);
}
/* The radio is the real control and stays in the tab order, only unseen; the pill
   around its label is what shows the choice. */
.author__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}
.author__presenter {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-steel);
  border-radius: var(--radius-pill);
  background-color: var(--color-surface);
  color: var(--color-muted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.author__presenter::before {
  content: "";
  width: 0.75rem;
  height: 0.75rem;
  border: 2px solid currentColor;
  border-radius: var(--radius-pill);
}
.author__presenter:hover { border-color: var(--color-primary); color: var(--color-primary); }
.author[data-presenter] .author__presenter {
  border-color: var(--color-primary);
  background-color: var(--color-primary);
  color: var(--color-on-dark);
}
.author[data-presenter] .author__presenter::before { background-color: currentColor; }
.author__presenter:has(.author__radio:focus-visible) {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}
.author__role .author__email { flex: 1 1 16rem; margin: 0; }
.author > .field-error { grid-column: 2; margin: 0; }
/* The radio is invisible, so "mark the presenter" has to colour the pill it sits in. */
.author__presenter:has(.author__radio[aria-invalid="true"]) {
  border-color: var(--color-danger);
  color: var(--color-danger);
  background-color: var(--color-danger-soft);
}

.abstract-button {
  display: inline-flex;
  align-items: center;
  height: var(--control-height);
  padding: 0 var(--space-4);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent);
  background-color: var(--color-surface);
  border: 1px solid var(--color-accent);
  border-radius: var(--control-radius);
  cursor: pointer;
  text-decoration: none; /* also worn by a link: "Submit another abstract" */
}
.abstract-button:hover { color: var(--color-accent-hover); border-color: var(--color-accent-hover); }
.abstract-button:disabled { color: var(--color-muted); border-color: var(--color-steel); cursor: not-allowed; }

/* The file control is ours, the input is still the browser's. The input keeps the
   file and keeps its place in the tab order -- it is made invisible, never
   display:none -- and the <label>, wearing .abstract-button, opens the picker for
   mouse and keyboard alike. Hiding the input also hides the name the browser used
   to print beside it, so __chosen prints the name and size instead. */

.abstract-file {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.abstract-field .abstract-file__input {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  opacity: 0;
}
.abstract-field .abstract-file__button { display: inline-flex; margin-bottom: 0; }
/* What takes focus cannot be seen, so the ring is drawn on the label. :focus and
   not :focus-visible: focus also lands here from the JS after a mouse press, and an
   indicator that is sometimes missing is worse than one that is sometimes extra.
   The declarations are the global :focus-visible in base.css, minus its
   border-radius: the label already carries --control-radius, and the ring follows
   the shape it is drawn around. */
.abstract-file__input:focus + .abstract-file__button {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}
/* Empty until a file is chosen, and left in the layout while it is: it is a
   role="status", and a live region has to be in the tree before it can speak.
   Empty it costs nothing here -- a zero-width flex item on the same row. */
.abstract-file__chosen {
  margin: 0;
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.abstract-consent { display: flex; gap: var(--space-3); align-items: flex-start; }
/* The notice is read before submitting, not in the way of it: one line that opens in
   place, with the fold's chevron at text size. */
.abstract-privacy { margin: var(--space-4) 0 0; font-size: var(--font-size-sm); color: var(--color-muted); }
.abstract-privacy p { margin: var(--space-2) 0 0; }
.abstract-privacy__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  cursor: pointer;
  list-style: none;
}
.abstract-privacy__summary::-webkit-details-marker { display: none; }
.abstract-privacy__summary:hover { color: var(--color-accent); }
.abstract-privacy__summary::after {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  margin-bottom: 0.15rem;
  color: var(--color-accent);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--duration-base) var(--ease-standard);
}
.abstract-privacy[open] > .abstract-privacy__summary::after {
  margin-bottom: -0.15rem;
  transform: rotate(-135deg);
}
.abstract-consent input { flex: 0 0 auto; margin-top: 0.2rem; }

.abstract-form .btn,
.abstract-actions .btn,
.abstract-cta .btn {
  display: inline-flex;
  align-items: center;
  height: var(--control-height);
  padding-block: 0;
  border: 0;
  border-radius: var(--control-radius);
  font-size: var(--font-size-base);
  cursor: pointer;
}
.abstract-form .btn:disabled { background-color: var(--color-muted); cursor: progress; }

.abstract-status { margin-top: var(--space-3); font-weight: var(--font-weight-semibold); }

.abstract-errors {
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-danger-soft);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
  border-left-width: 6px;
  border-radius: var(--radius-md);
}
/* base.css colours h1-h4 directly, so the inherited red loses and the title comes
   out navy inside the red box. Said explicitly here, as .abstract-done does for the
   success panel's heading. */
.abstract-errors__title { font-size: var(--font-size-md); margin-bottom: var(--space-3); color: var(--color-danger); }
.abstract-errors ul { margin: 0; }

.abstract-done { max-width: var(--max-width-prose); }
.abstract-link code {
  display: block;
  padding: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--font-size-md);
  overflow-wrap: anywhere;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.abstract-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-2); }

@media (min-width: 48rem) {
  .author { grid-template-columns: 2rem minmax(0, 1fr); }
  /* Pill, e-mail and icons on one line: the e-mail takes what is left instead of a
     line of its own, which pushed the icons to a third row on the presenter's row. */
  .author__role { flex-wrap: nowrap; }
  .author__role .author__email { flex: 1 1 auto; min-width: 0; }
  .author__fields { grid-template-columns: minmax(0, 0.9fr) minmax(0, 0.9fr) minmax(0, 1.3fr) minmax(0, 0.8fr); }
  /* The first row's labels head the columns; the others keep theirs for assistive
     technology only, where each field is also named with its author's number. */
  .author + .author .author__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .author + .author .author__num { margin-top: 0.4rem; }
}

/* /abstracts/view: what was submitted, read-only. Neutral, not the success panel: the
   reader may come back weeks later from the confirmation mail. */
.abstract-view { max-width: var(--max-width-prose); }
.abstract-view__list { margin: var(--space-5) 0; }
.abstract-view__list > div {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}
.abstract-view__list dt { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-muted); }
.abstract-view__list dd { margin: var(--space-1) 0 0; overflow-wrap: anywhere; }
.abstract-view__authors { margin: 0; padding-left: var(--space-5); }
.abstract-view__body { white-space: pre-line; }


/* The two dates the page exists to announce, in the label voice the footer
   already uses for its own dates. */
.abstract-dates {
  display: grid;
  gap: var(--space-4);
  margin: var(--space-5) 0 0;
  max-width: var(--max-width-prose);
}
.abstract-dates dt {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}
.abstract-dates dd { margin: var(--space-1) 0 0; font-size: var(--font-size-md); }

@media (min-width: 40rem) {
  .abstract-dates { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}

/* Native <details>, no JS of our own. The summary is a heading you can close,
   not an accordion bar: the h3 size and the display face, with the same stroked
   chevron language as the nav. */
.abstract-fold { margin-top: var(--space-7); }
.abstract-fold__summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-2) 0;
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-snug);
  color: var(--color-primary);
  cursor: pointer;
  list-style: none;
}
.abstract-fold__summary::-webkit-details-marker { display: none; }
.abstract-fold__summary:hover { color: var(--color-accent); }
.abstract-fold__summary::after {
  content: "";
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  margin-bottom: 0.2rem;
  color: var(--color-accent);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--duration-base) var(--ease-standard);
}
.abstract-fold[open] > .abstract-fold__summary::after {
  margin-bottom: -0.2rem;
  transform: rotate(-135deg);
}
.abstract-fold__body { margin-top: var(--space-4); }

.abstract-cta { margin-top: var(--space-6); }

/* The form fold has nothing in it until the config loads and the JS unhides the
   form, and an empty fold invites a click that does nothing. */
.abstract-fold--form:has(> form[hidden]) { display: none; }

/* One way in, and it is the button. The fold keeps its <summary> because the JS
   opens and closes this <details>, but a second, quieter control to the same
   place is what the audit found. The form's own h2 is the block's one title. */
.abstract-fold--form > .abstract-fold__summary { display: none; }
/* Once the form is open and loaded, the button has done its job. */
.page-layout__main:has(> .abstract-fold--form[open] > form:not([hidden])) .abstract-cta { display: none; }

.abstract-steps { list-style: none; padding: 0; max-width: var(--max-width-prose); }
.abstract-steps > li {
  margin: 0 0 var(--space-5);
  padding-left: var(--space-5);
  border-left: 3px solid var(--color-accent-soft);
}
.abstract-steps h3 { font-size: var(--font-size-md); margin-bottom: var(--space-2); }
.abstract-steps ol { padding-left: var(--space-5); }

.abstract-topics li { max-width: var(--max-width-prose); }

.abstract-consent--plain { margin-top: var(--space-5); }

.markup-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.markup-button {
  min-width: var(--control-height);
  height: var(--control-height);
  padding: 0 var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-steel);
  border-radius: var(--control-radius);
  cursor: pointer;
  touch-action: manipulation;
}
.markup-button:hover { border-color: var(--color-accent); color: var(--color-accent); }
.markup-button[aria-pressed="true"] {
  color: var(--color-on-dark);
  background-color: var(--color-primary);
  border-color: var(--color-primary);
}
.markup-toolbar select {
  display: inline-block;
  width: auto;
  height: var(--control-height);
  min-width: 0;
  padding: 0 var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-steel);
  border-radius: var(--control-radius);
}

/* ── State colour ────────────────────────────────────────────────────────────
   One treatment, the panel; the alternatives are gone and their contrast ratios
   are kept with the project notes.

   Colour is added ON TOP of what already carried the state -- the "Error:"
   text, the 2px border and inset bar, aria-invalid, role="status" -- and never
   replaces any of it. Red and green are almost the same luminance (0.110
   against 0.124), so to a red-green colour-blind reader they are one colour
   and the shape has to keep doing the work.

   NONE of the three strong tokens is usable on navy (1.84 / 2.01 / 2.42:1), so
   no state colour goes inside a .callout. The -soft tints are fills only, at
   1.04-1.06:1 against the page: they always need the strong border beside them.

   The nine hooks. Where a hook already had a rule of its own above, the colour was
   folded into it rather than repeated here, so the first one you meet is the whole
   answer:
     .abstract-form [aria-invalid="true"]           a field that failed: the control
       and .field-error                             itself, and the message the JS
                                                    hangs on its .abstract-field
     .abstract-file__button                         the same, on #pdf's label
     .abstract-errors                               the summary / server refusal
     .abstract-status[data-tone="danger"]           Turnstile could not load
     .abstract-count[data-over="true"]              past the character limit
     .abstract-done                                 saved (the success view)
     .abstract-notice--warning  (#done-pdf)         saved, PDF not attached */

/* #pdf itself is invisible, so colouring the failed field paints where nobody can
   look: it has to colour the label that stands in for it. This selector already
   beats .abstract-button:hover on specificity, so it holds while the pointer is on
   it. The .field-error text is appended to the .abstract-field, not to the input,
   and still shows. */
.abstract-file__input[aria-invalid="true"] + .abstract-file__button {
  color: var(--color-danger);
  background-color: var(--color-danger-soft);
  border-color: var(--color-danger);
}
.abstract-status[data-tone="danger"] { color: var(--color-danger); }
.abstract-errors a { color: inherit; }
.abstract-done {
  padding: var(--space-5) var(--space-6);
  background-color: var(--color-success-soft);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-lg);
}
.abstract-done > .heading--accent { color: var(--color-success); }
.abstract-done > .heading--accent::after { background-color: var(--color-success); }
.abstract-notice--warning {
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-warning-soft);
  color: var(--color-warning);
  border: 1px solid var(--color-warning);
  border-left-width: 6px;
  border-radius: var(--radius-md);
}
/* The base .abstract-notice is a navy panel, so its links are --color-on-dark. On this
   pale tint that is 1.00:1 -- the same colour, measured 2026-09-22. #done-pdf carries no
   link today, but the class is the form's warning panel and a link in one would vanish,
   so the rule follows the background it sits on. Same fix as .abstract-errors a just above. */
.abstract-notice--warning a { color: inherit; }
.abstract-notice--warning a:hover { color: var(--color-text); }

/* Printing /abstracts/view is the receipt: the submission and nothing of
   the site around it. The nav is its own element, not part of the header. And the
   page grid goes back to a plain block: Chrome would not split that grid item across
   pages, so on the first print it moved the whole submission to page 2 and left page 1
   holding only the nav. */
@page { margin: 16mm; }
@media print {
  .skip-link,
  .site-header,
  .site-nav,
  .site-footer,
  .sponsor-rail { display: none !important; }
  .section { padding: 0; }
  .page-layout { display: block; }
  .abstract-view { max-width: none; }
  /* Focused on arrival for screen readers; the ring means nothing on paper. */
  .abstract-view:focus { outline: none; box-shadow: none; }
  .abstract-view__print { display: none; }
  /* With the header gone, the paper still has to say which conference this is. */
  .abstract-view::before {
    content: "ASD 2027 · Area Selective Deposition Workshop · Portland, Oregon, April 4–7, 2027";
    display: block;
    margin-bottom: var(--space-4);
    font-size: var(--font-size-sm);
    color: var(--color-muted);
  }
  .abstract-view__list > div { break-inside: avoid; }
  .abstract-view__list > div:last-child { break-inside: auto; }
  .abstract-view__list dt { break-after: avoid; }
}
