/* ==========================================================================
   WoWMoM 2027 — stylesheet

   Built on the tokens in tokens.css, which must be loaded first.
   Replaces the inherited Bootstrap 3 + jQuery template (~140 KB of CSS of
   which about 5% was used) with CSS Grid and no JavaScript dependency for
   layout. The visual language — Oswald over Lora, the WoWMoM teal, the
   nav / content / aside split — is carried over deliberately.

   Sections:
     1. Fonts        4. Masthead      7. Aside panels
     2. Reset        5. Navigation    8. Footer
     3. Layout       6. Content       9. Responsive, motion, print
   ========================================================================== */

/* --- 1. Fonts -------------------------------------------------------------
   Self-hosted so the site makes no third-party requests. If the .woff2 files
   are absent the fallback stacks in tokens.css take over cleanly. */

/* Both are variable fonts: one file per family covers the whole 400–700
   range, so there is no separate bold file to keep in step. Latin subset
   only — 21 KB Oswald, 37 KB Lora. Both are SIL Open Font Licence 1.1, and
   the licence text must ship alongside them: assets/fonts/OFL-Oswald.txt and
   assets/fonts/OFL-Lora.txt. Do not exclude those from a deploy. */

@font-face {
  font-family: "Oswald";
  src: url("../fonts/oswald-var.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: "Lora";
  src: url("../fonts/lora-var.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}

/* --- 2. Reset -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-tight);
  color: var(--color-accent);
  margin: 0 0 var(--space-4);
}

/* Section headings keep the inherited uppercase treatment, but h1 and the
   masthead title do not. Uppercasing turns the WoWMoM wordmark into WOWMOM,
   and the mixed casing is the brand. Any heading likely to contain the
   wordmark must stay in natural case. */
h2, h3, h4, h5 { text-transform: uppercase; }

h1 { font-size: var(--text-hero); }
h2 { font-size: var(--text-h2); margin-top: var(--space-7); }
h3 { font-size: var(--text-h3); margin-top: var(--space-6); color: var(--color-text); }

p, ul, ol, table, figure { margin: 0 0 var(--space-4); }

a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
a:hover { color: var(--color-accent-dark); }

/* One visible focus style everywhere. The inherited template changed colours
   on mouseover only, leaving keyboard users with no indication at all. */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

img { max-width: 100%; height: auto; }

.skip-link {
  position: absolute;
  left: -9999px;
  background: var(--color-accent);
  color: #fff;
  padding: var(--space-3) var(--space-4);
  z-index: 100;
}
.skip-link:focus {
  left: var(--space-4);
  top: var(--space-2);
}

.tbc { color: var(--color-muted); font-style: italic; }

/* --- 3. Layout ------------------------------------------------------------- */

.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
}

/* --- 4. Masthead ----------------------------------------------------------- */

.masthead {
  border-bottom: 4px solid var(--color-accent);
  padding: var(--space-5) var(--space-5) var(--space-4);
}
.masthead__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  /* Logo and wordmark sit side by side. They wrap to two rows on narrow
     screens, which is why the logo is a flex item with its own margin
     rather than a float. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
}
.masthead__words {
  /* Take the remaining width so the dates line wraps against the logo
     rather than pushing it off the row. */
  flex: 1 1 16rem;
}
/* Height-driven, because the mark is wide (357x157) and it is the cap height
   that must agree with the wordmark beside it, not the width. The intrinsic
   width/height attributes in the markup reserve the right box before the
   image loads, so the masthead does not jump. */
.masthead__logo {
  height: 4.5rem;
  width: auto;
  flex: none;
}
.masthead__eyebrow {
  font-family: var(--font-heading);
  font-size: var(--text-small);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  color: var(--color-muted);
  margin: 0 0 var(--space-2);
}
.masthead__title {
  font-family: var(--font-heading);
  font-size: var(--text-hero);
  font-weight: 700;
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-tight);
  margin: 0;
}
.masthead__title a { color: var(--color-accent); text-decoration: none; }
.masthead__meta {
  font-family: var(--font-heading);
  font-size: var(--text-body);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  color: var(--color-text);
  margin: var(--space-2) 0 0;
}
.masthead__sep { color: var(--color-muted); margin: 0 var(--space-2); }

/* Key facts strip, immediately below the masthead.
   This replaced a full-width band of flat accent colour. Two problems with
   that band: it stacked a second large teal element directly under the
   masthead's teal rule, and being empty it read as an unfinished placeholder
   rather than a decision. Carrying three real facts fixes both — the strip
   now earns its space by orienting a first-time visitor. */
.factbar {
  background: var(--color-bg-alt);
  border-bottom: var(--rule);
  padding: var(--space-5);
}
.factbar__list {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: var(--container-max);
  display: grid;
  gap: var(--space-5);
  /* One column, then three. Deliberately no auto-fit intermediate: at two
     columns the third fact wraps to a new row and its divider would sit at
     the start of that row, reading as a stray rule. */
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) {
  .factbar__list { grid-template-columns: repeat(3, 1fr); }
}
.fact {
  margin: 0;
  /* Divider between facts, suppressed on the first so it never leads. */
  padding-left: var(--space-5);
  border-left: 3px solid var(--color-accent-tint);
}
.fact:first-child { padding-left: 0; border-left: 0; }

.fact__value {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--text-h3);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-tight);
  color: var(--color-accent);
}
.fact__note {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-small);
  color: var(--color-muted);
}

/* Whole-block link. The underline sits on the value alone — underlining the
   note as well would make the strip look like a wall of links. */
.fact__link { display: block; text-decoration: none; }
.fact__link .fact__value {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.fact__link:hover .fact__value { color: var(--color-accent-dark); }
.fact__link:hover .fact__note  { color: var(--color-text); }

/* Stacked on narrow screens the left borders would form one ragged vertical
   line down the page, so they become top borders instead. */
@media (max-width: 47.999rem) {
  .fact {
    padding: var(--space-4) 0 0;
    border-left: 0;
    border-top: 3px solid var(--color-accent-tint);
  }
  .fact:first-child { padding-top: 0; border-top: 0; }
}

/* --- 5. Navigation --------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-heading);
  font-size: var(--text-body);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  color: #fff;
  background: var(--color-accent);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}
.nav-toggle:hover { background: var(--color-accent-dark); }
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 1rem;
  height: 2px;
  background: #fff;
  content: "";
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before { position: absolute; top: -5px; }
.nav-toggle__bars::after  { position: absolute; top: 5px; }

/* Two menus, one list, never both on screen.

   .site-nav is the sidebar column of the three-column layout, shown from
   64rem. Below that the page has no sidebar, and the menu is .site-menu,
   which sits inside the masthead directly under the button that opens it.
   It used to open in the sidebar slot instead, and on the homepage that slot
   comes after the action strip - so tapping Menu revealed a list a whole
   band further down the page. Both are filled from SITE_NAV by include.js,
   and display:none takes the hidden one out of the accessibility tree too. */
.site-nav { display: none; }

.site-menu {
  display: none;
  max-width: var(--container-max);
  margin: var(--space-4) auto 0;
  padding-top: var(--space-4);
  border-top: var(--rule);
}
.site-menu.is-open { display: block; }

.site-nav__list { list-style: none; margin: 0; padding: 0; }
.site-nav__list li { margin-bottom: var(--space-3); }

.site-nav__list a {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--text-small);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  line-height: 1.2;
  color: var(--color-muted);
  text-decoration: none;
}
.site-nav__list a:hover,
.site-nav__list a:focus-visible { color: var(--color-accent); }

.site-nav__list a.is-current {
  color: var(--color-accent);
  border-left: 3px solid var(--color-accent);
  margin-left: -0.75rem;
  padding-left: 0.5rem;
}

/* --- 6. Content ------------------------------------------------------------ */

.content > :first-child { margin-top: 0; }

/* One measure for the whole column, not just for paragraphs.
   Capping only <p> was a mistake: lists, tables and callouts then ran the
   full width of the column while the prose stayed narrow, so nothing lined
   up and anything centred appeared pushed to the right. Everything now
   shares the same 68-character measure, which is also comfortable reading
   width for Lora at 16px. */
.content { max-width: 68ch; }

/* Justified prose. Paragraphs only — lists, tables and cells keep their
   ragged right, because justifying a short list item stretches it into
   something that reads as a rendering fault rather than a decision.

   `hyphens: auto` belongs with it and should not be removed on its own.
   Justification works by opening the word spaces until the line fills the
   measure, so a line carrying "interoperability" or "IoT-edge-cloud
   continuum" - both of which the Call for Papers has - has to open them very
   wide, and the gaps then line up vertically into rivers down the paragraph.
   Hyphenation gives the line breaker a second place to take up that slack.
   It relies on lang="en" on <html>, which every page sets; without the
   attribute the browser has no dictionary and silently does nothing. */
.content p {
  text-align: justify;
  hyphens: auto;
}

.content ul, .content ol { padding-left: var(--space-5); }
.content li { margin-bottom: var(--space-2); }

blockquote {
  margin: var(--space-5) 0;
  padding: var(--space-2) var(--space-5);
  border-left: 4px solid var(--color-accent-tint);
  color: var(--color-text);
  font-style: italic;
}

table { border-collapse: collapse; width: 100%; }
th, td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: var(--rule);
  vertical-align: top;
}
th {
  font-family: var(--font-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  font-size: var(--text-small);
  color: var(--color-accent);
}

/* Deadlines rendered inside a page body rather than in the sidebar. */
.deadline-table th[scope="row"] {
  font-family: var(--font-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  font-size: var(--text-small);
  color: var(--color-text);
  width: 55%;
}
.deadline-table td { color: var(--color-accent); font-weight: 700; }

/* Long lists such as the topics of interest.
   Single column deliberately. These were previously set in two columns, but
   once the content column is held to a readable measure two columns leave
   roughly 30 characters each — too narrow for entries like "Modelling,
   analysis and performance evaluation of wireless, mobile and multimedia
   networks", which then wrapped to three ragged lines. One column also
   matches how previous editions presented the topics. */
.topic-list { padding-left: var(--space-5); }

/* Callout for something the reader must not miss and could act on wrongly:
   a deadline extension, a change of venue, a figure that may still move.

   It is NOT for announcing that something has yet to be announced. Missing
   content is the site's normal state for most of the cycle and is carried by
   .placeholder and by TBA, which are quiet by design. Every page once opened
   with a .notice saying its content was in preparation; eighteen simultaneous
   callouts say nothing, and left the class with no force for the deadline
   extension it exists to carry. Before adding one, ask what a reader would do
   differently on reading it. If the answer is nothing, it is not a notice. */
.notice {
  background: var(--color-bg-alt);
  border-left: 4px solid var(--color-accent);
  padding: var(--space-4) var(--space-5);
  margin: 0 0 var(--space-6);
}
.notice > :last-child { margin-bottom: 0; }

/* Marks a section whose content is not yet written, so unfinished pages read
   as deliberate rather than broken. The 2023 site shipped an empty blank.html
   for Travel Grants; this is the alternative. */
.placeholder {
  border: 1px dashed var(--color-border);
  background: var(--color-bg-alt);
  padding: var(--space-5);
  color: var(--color-muted);
  font-style: italic;
}

/* Journal fast-track partners. Centred, which is how previous editions
   presented them — but via CSS, not the deprecated <center> element. */
/* The `.content ul` rule above sets a left padding for bullets, and it beats
   a single class selector on specificity. Qualifying with .content wins it
   back — without this the centred text sits visibly off-centre. */
.content .journal-list {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: var(--space-4) var(--space-5);
  text-align: center;
  background: var(--color-bg-alt);
  border-top: 3px solid var(--color-accent);
}
.journal {
  margin-bottom: var(--space-2);
  font-size: var(--text-h3);
  font-family: var(--font-heading);
}
.journal__meta {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-small);
  color: var(--color-muted);
}

/* A third-party mark inside a link - currently only the LinkedIn bug.

   THIS IS THE ONE PLACE A COLOUR COMES FROM OUTSIDE tokens.css, and it is
   deliberate: LinkedIn's brand terms allow their logo to link to a LinkedIn
   page only if it is used unmodified, which rules out tinting it to the
   accent. The IEEE and UCI marks in the sidebar are outside the palette for
   the same reason. See DESIGN.md 3.

   Sized against the line's own type rather than in pixels, so it tracks the
   text at any zoom. The natural size is on the img element, so the line does
   not reflow as the image loads. */
.link-icon {
  height: 1.4em;
  width: auto;
  vertical-align: -0.35em;
  margin-right: var(--space-2);
}

/* The mark needs room around it - LinkedIn's guidance asks for clear space,
   and a logo crowded against body copy reads as an afterthought either way.
   So the link stands on its own line rather than sitting inside a sentence. */
.social {
  margin-top: var(--space-4);
}

.social a {
  display: inline-flex;
  align-items: center;
}

/* --- 6b. Committees ---------------------------------------------------------
   Roles sit in a grid so a page of mostly-empty roles still reads as an
   organisation chart rather than a column of "To be announced". */

.committee + .committee { margin-top: var(--space-7); }

/* One block per accepted workshop. The acronym is the h2, which already
   carries its own top margin, so the block needs no spacing rule of its own —
   only the full title under the acronym needs setting apart. */
.workshop__name {
  margin-bottom: var(--space-4);
  color: var(--color-muted);
}

.role-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5) var(--space-7);
}
@media (min-width: 40rem) {
  .role-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.role { break-inside: avoid; }
.role__title {
  font-size: var(--text-small);
  color: var(--color-muted);
  margin: 0 0 var(--space-2);
  /* Overrides the h3 rule, which is body-coloured and larger. */
}
.role__tba { margin: 0; }

.role__people { list-style: none; margin: 0; padding: 0; }
.role__people--wide {
  /* Long single lists (TPC members) flow into two columns. Not three: the
     content column is held to a 68-character measure, and three columns
     would leave too little room for a name plus its affiliation. */
  columns: 2;
  column-gap: var(--space-7);
}

.person { margin: 0 0 var(--space-3); break-inside: avoid; }
.person__name {
  display: block;
  font-family: var(--font-heading);
  font-size: var(--text-body);
  color: var(--color-text);
}
a.person__name { color: var(--color-accent); }
.person__affil {
  display: block;
  font-size: var(--text-small);
  color: var(--color-muted);
  line-height: 1.4;
}

/* --- 6c. Draft review — TEMPORARY ---------------------------------------------
   The scope changes the 2027 rename implies, marked inline in the copy itself:
   wording that is going struck through in red, wording proposed in its place on
   a pale tint. Nothing else - no panel, no label, no surrounding chrome. The
   passages have to read as the pages they will become, and a box around them
   would have the TPC Chairs judging a review document instead.

   Marking is <del> and <ins>, which carry the right semantics for assistive
   technology rather than only a colour difference.

   THIS IS NOT PUBLICATION MARKUP. Before the site goes live, delete every <del>
   and unwrap every <ins> - then delete this section and the two draft-review
   tokens in tokens.css. `grep -rn REDLINE *.html` finds every passage.
   ============================================================================ */

/* Copy that goes. The strike is red; the words under it drop to muted, so a
   glance separates them from the live text even where the rule is faint at
   small sizes. */
.redline-cut {
  color: var(--color-muted);
  text-decoration: line-through;
  text-decoration-color: var(--color-redline);
  text-decoration-thickness: 2px;
}

/* Copy proposed in its place. Full body colour and weight - it has to read
   exactly as it will read once published, so the tint is what marks it as
   undecided, not a change in how the words are set. Browsers underline <ins>
   by default, which would fight the strike beside it. box-decoration-break
   keeps the tint intact where a long proposal wraps across lines. */
.redline-add {
  padding: 0.1em 0.15em;
  background: var(--color-proposed-bg);
  border-radius: var(--radius);
  text-decoration: none;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* --- 7. Aside panels -------------------------------------------------------- */

.aside { font-size: var(--text-small); }

.panel {
  background: var(--color-bg-alt);
  border-top: 3px solid var(--color-accent);
  padding: var(--space-4) var(--space-5) var(--space-5);
  margin-bottom: var(--space-6);
}
.panel__title {
  font-size: var(--text-h3);
  margin: 0 0 var(--space-4);
  color: var(--color-accent);
}
.panel__note {
  margin: var(--space-4) 0 0;
  color: var(--color-muted);
  font-size: var(--text-small);
  line-height: 1.45;
}

.deadline-list { list-style: none; margin: 0; padding: 0; }
.deadline {
  padding: var(--space-3) 0;
  border-bottom: var(--rule);
}
.deadline:last-child { border-bottom: 0; }
.deadline__label {
  display: block;
  font-family: var(--font-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  color: var(--color-text);
}
.deadline__date { color: var(--color-accent); font-weight: 700; }

.badge {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  background: var(--color-accent);
  color: #fff;
  font-family: var(--font-heading);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  border-radius: var(--radius);
}

.sponsor-list { list-style: none; margin: 0; padding: 0; }
.sponsor { margin-bottom: var(--space-4); }
/* Sponsor marks vary wildly in proportion - the two IEEE wordmarks are about
   3.3:1, the UCI seal is square. Capping the height alone would let a
   wordmark run 219px wide and overflow this panel, so both axes are capped:
   the wordmarks are bound by height, the seal by nothing, and each ends up
   the same 3.5rem tall. */
.sponsor img {
  max-height: 3.5rem;
  max-width: 100%;
  width: auto;
  height: auto;
}
.logo-placeholder {
  display: block;
  padding: var(--space-3);
  border: 1px dashed var(--color-border);
  color: var(--color-muted);
  font-family: var(--font-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-heading);
  font-size: 0.8rem;
  text-align: center;
}

/* --- 8. Footer --------------------------------------------------------------- */

.footer {
  border-top: 4px solid var(--color-accent);
  background: var(--color-bg-alt);
  padding: var(--space-6) var(--space-5);
  font-size: var(--text-small);
}
.footer__inner { max-width: var(--container-max); margin: 0 auto; }
.footer__line { margin: 0 0 var(--space-2); }
/* Otherwise the last line's margin stacks on the footer's own padding and
   the block sits visibly off-centre between the two rules. */
.footer__line:last-child { margin-bottom: 0; }
.footer__muted { color: var(--color-muted); }

/* --- 9. Responsive ------------------------------------------------------------ */

/* 48rem — the aside comes up beside the content. */
@media (min-width: 48rem) {
  .layout {
    grid-template-columns: var(--col-main) var(--col-aside);
    gap: var(--space-7);
  }
  .layout--wide { grid-template-columns: 1fr; }
}

/* 64rem — the full three-column arrangement of previous editions, and the
   navigation becomes permanent so the menu button is no longer needed. */
@media (min-width: 64rem) {
  .layout {
    grid-template-columns: var(--col-nav) var(--col-main) var(--col-aside);
  }
  /* Pages with no aside. Without this the content would stay in the middle
     column and leave the third one empty — the grid does not close up by
     itself, because the track list is explicit.

     The second track must be --col-main + --col-aside (7fr + 3fr), NOT a
     bare 1fr: fr units are shares of the whole row, so pairing 2fr with 1fr
     would give the navigation two thirds of the page and squeeze the content
     into a strip on the right. Keeping the total at 12fr holds the nav to
     the same width it has on three-column pages. */
  .layout--wide { grid-template-columns: var(--col-nav) 10fr; }

  /* On a page with no aside the second track is far wider than the text
     measure, so the content would sit hard against the navigation with a
     large empty area to its right. Centre it in the space it has. Three-
     column pages are left alone — there the content is already framed by the
     aside, and centring it would break alignment with the panels. */
  .layout--wide .content { margin-inline: auto; }
  .site-nav {
    display: block;
    grid-column: auto;
  }
  /* Listed with .is-open so an open small-screen menu cannot outrank this
     when the window is widened. */
  .nav-toggle,
  .site-menu,
  .site-menu.is-open { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .site-nav, .site-menu, .nav-toggle, .skip-link { display: none; }
  .layout { display: block; max-width: none; padding: 0; }
  body { color: #000; font-size: 11pt; }
  a { color: #000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
