/*
==================================================================
NEWS PAGE
Page-scoped styles for news.html.

The supplied images are DESIGNED CARDS (near-square, with their own
frame, logos and padding baked in) rather than photographs - so they
are fitted with object-fit: contain on a near-square box. Cropping
them with `cover` would cut off the branding along their edges.
==================================================================
*/

.tt-nw-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.4vw, 2rem);
}

/* ==================================================================
   HUB PAGINATION (assets/js/news.js)
   Same shape as the gallery pager in events-page.css. The two live in
   different stylesheets because news.html does not load events-page.css
   and there is no shared pager component to put it in - duplicating
   ~30 lines beats making every news page download the gallery sheet.
   ================================================================== */
.tt-nw-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.4rem;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
.tt-nw-page {
  min-width: 2.4rem;
  height: 2.4rem;
  padding: 0 0.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--tt-border);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
  font-family: var(--tt-font-primary);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--tt-dark);
  cursor: pointer;
  transition: var(--tt-transition-fast);
}
.tt-nw-page:hover:not(:disabled),
.tt-nw-page:focus-visible {
  color: var(--tt-primary);
  border-color: rgba(var(--tt-primary-rgb), 0.4);
}
.tt-nw-page:disabled { opacity: 0.45; cursor: default; }
.tt-nw-page.is-active {
  background: var(--tt-gradient-primary);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 10px 22px -10px rgba(var(--tt-primary-rgb), 0.75);
}

/* ==================================================================
   STORY PHOTO CAROUSEL (assets/js/news.js)
   On a story with more than one photograph this REPLACES the static
   .tt-ar-cover - the carousel's first slide is that same photo, so
   showing both would just print it twice. A single-photo story keeps
   the plain cover and no carousel is emitted.

   The track is a flex row of full-width slides moved with transform,
   not by re-ordering the DOM: transform is compositor-only, so the
   slide costs no layout work every two seconds.

   overflow:hidden is safe HERE - it is a fixed-size box, not a page
   ancestor. Hard rule 1 is about html/body/.page-wrapper, where it
   silently kills every position:sticky on the site.
   ================================================================== */
/* 38rem centred, matching .tt-ar-cover in blog.css exactly. That is the width
   a single-photo story already uses, so the two story types read as the same
   page rather than two designs. Full container width put a ~700px-tall photo
   between the heading and the copy and pushed the article below the fold. */
/* ==================================================================
   STORY PAGE LAYOUT - LEFT ALIGNED
   Everything hangs off one left edge: the breadcrumb, the headline,
   the photo and the copy. The rail on the right is what makes that
   possible without the page looking half-used - drop it and a
   left-aligned 38rem column leaves a screen's worth of dead space.

   blog.css centres .tt-ar-hero-inner and offsets .tt-ar-body; both
   are overridden here rather than changed there, because the blog
   articles still want the centred treatment.
   ================================================================== */
.tt-nw-hero-inner {
  max-width: 68rem;
  margin-inline: auto;
  text-align: left;
}
.tt-nw-hero-inner .tt-ar-crumbs { justify-content: flex-start; }

.tt-nw-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17rem;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: start;
  max-width: 68rem;
  margin-inline: auto;
}
.tt-nw-main { min-width: 0; }
.tt-nw-main .tt-ar-body {
  max-width: none;
  margin-inline-start: 0;
}
.tt-nw-main .tt-ar-cover { max-width: 100%; margin-inline: 0; }

/* Standfirst under the h1. Same sentence the hub card and the search result
   carry, so arriving from either reads as continuous. */
.tt-nw-standfirst {
  max-width: 44rem;
  margin: 0.85rem 0 0;
  font-size: 1.1rem;
  line-height: 1.65;
  color: var(--tt-muted);
}

/* ------------------------------------------------------------------
   PULL-QUOTE
   NOT a quotation from a person - a line of the story's own argument,
   set large. Nobody is credited because nobody said it. An orange
   rule on the LEFT rather than quotation marks, so it reads as
   emphasis rather than as attributed speech.
   ------------------------------------------------------------------ */
.tt-nw-pull {
  margin: clamp(1.75rem, 3.5vw, 2.5rem) 0;
  padding: 0.25rem 0 0.25rem 1.35rem;
  border-left: 3px solid var(--tt-primary);
  font-family: var(--tt-font-poppins, var(--tt-font-primary));
  font-size: clamp(1.2rem, 2.2vw, 1.45rem);
  font-weight: 600;
  line-height: 1.45;
  color: var(--tt-dark);
}

/* ------------------------------------------------------------------
   "AT A GLANCE" RAIL
   Sticky, because the page is long enough that the CTA would
   otherwise scroll away and never come back. Everything in it is
   derived - client, milestone, photo count - so it states nothing the
   page does not already know.
   ------------------------------------------------------------------ */
.tt-nw-aside { position: sticky; top: calc(var(--tt-header-height, 96px) + 1.5rem); }
.tt-nw-facts {
  padding: 1.35rem 1.4rem 1.5rem;
  border: 1px solid var(--tt-border);
  border-radius: 16px;
  background: rgba(243, 244, 246, 0.6);
}
.tt-nw-facts-title {
  margin: 0 0 0.9rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--tt-muted);
}
.tt-nw-facts-list { margin: 0; }
.tt-nw-facts-list dt {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--tt-muted);
}
.tt-nw-facts-list dd {
  margin: 0 0 0.85rem;
  font-weight: 600;
  color: var(--tt-dark);
  line-height: 1.4;
}
.tt-nw-facts-list dd:last-of-type { margin-bottom: 1.15rem; }
.tt-nw-facts-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--tt-primary);
  text-decoration: none;
}
.tt-nw-facts-cta:hover { text-decoration: underline; }

@media (max-width: 991.98px) {
  /* The rail becomes a block under the story rather than a squeezed column. */
  .tt-nw-layout { grid-template-columns: minmax(0, 1fr); }
  .tt-nw-aside { position: static; }
}

.tt-nw-slider {
  position: relative;
  width: 100%;
  max-width: 100%;
  /* Room UNDER the slides for the dots. They used to sit over the bottom of
     the image, which on these cards is where the caption and both logos are -
     so the control covered the content it was there to help you browse. */
  padding-bottom: 1.9rem;
  /* margin-inline 0, not auto: it sits in the left column now and must share
     that column's left edge with the copy below it. */
  margin: clamp(1.5rem, 3vw, 2.5rem) 0 0;
  border-radius: 16px;
  border: 1px solid var(--tt-border);
  overflow: hidden;
  background: #fff;
}
.tt-nw-slides {
  display: flex;
  transition: transform 0.5s ease;
}
.tt-nw-slider-static .tt-nw-slides { transition: none; }

.tt-nw-slide {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
}
/* CONTAIN, NOT COVER, and 3/2 to match the art.
   These are not photographs to be cropped - they are designed cards, with the
   caption ("Go-Live Ceremony") and both logos laid out along the bottom edge.
   `cover` in a 16/9 box cut exactly that strip off every slide, which is the
   one part of the image carrying the information.
   The fixed ratio still does its real job: stopping a 1.5 image between two
   1.6 ones from resizing the whole box mid-slide. */
.tt-nw-slide img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  background: rgba(243, 244, 246, 0.85);
}

/* The prev/next arrows were removed on 2026-08-31. The dots are the only
   control now: they carry the same function, they say how many photos there
   are (which arrows never did), and they do not sit on top of the artwork.
   Keyboard users still get ArrowLeft/ArrowRight from news.js, and each dot is
   a real focusable button. */

/* In the strip below the slides, so nothing is covered. Fourteen dots have to
   fit on a phone too, hence the wrap. */
.tt-nw-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.55rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem;
}
/* On a light strip rather than over a photo, so the resting dot needs a solid
   fill instead of the translucent white it used when it sat on the image. */
.tt-nw-dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(16, 24, 40, 0.22);
  cursor: pointer;
  transition: var(--tt-transition-fast);
}
.tt-nw-dot:hover { background: rgba(var(--tt-primary-rgb), 0.55); }
.tt-nw-dot.is-active { background: var(--tt-primary); width: 1.3rem; border-radius: 999px; }

/* ==================================================================
   "MORE NEWS" STRIP (story pages)
   Three cards, so every story is linked from three others and none is
   reachable only from the hub. Reuses .tt-nw-card wholesale - a
   second card design for the same content would be a maintenance
   liability and would read as a different site.
   ================================================================== */
.tt-nw-more-section { padding-top: 0; }
.tt-nw-more {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.6rem);
}
/* These cards are secondary, so they sit lighter than the hub's: no drop
   shadow, and the title steps down from the hub's h2 size. */
.tt-nw-more .tt-nw-card { box-shadow: none; }
.tt-nw-more .tt-nw-title { font-size: 1.05rem; line-height: 1.45; }
.tt-nw-more .tt-nw-body { padding: 1rem 1.1rem 1.2rem; }

@media (max-width: 991.98px) {
  .tt-nw-more { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The third card would sit alone on a half-width row. */
  .tt-nw-more .tt-nw-card:nth-child(3) { display: none; }
}
@media (max-width: 575.98px) {
  .tt-nw-more { grid-template-columns: minmax(0, 1fr); }
  .tt-nw-more .tt-nw-card:nth-child(3) { display: flex; }
}

.tt-nw-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--tt-border);
  border-radius: 20px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04),
              0 10px 26px -16px rgba(16, 24, 40, 0.22);
  overflow: hidden;
  transition: var(--tt-transition-standard);
}
.tt-nw-card:hover {
  border-color: rgba(var(--tt-primary-rgb), 0.4);
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.05),
              0 20px 40px -14px rgba(var(--tt-primary-rgb), 0.26);
  transform: translateY(-4px);
}

/* ---------- Media ---------- */
/* 3/2, not 1/1. Every news image is a landscape co-branded card at roughly
   1.5-1.6 (924x579, 1600x1066), so a square box letterboxed each one into a
   third of a screen of empty grey and made the card enormous. 3/2 matches the
   art almost exactly, so contain has almost nothing left to letterbox. */
.tt-nw-media {
  position: relative;
  aspect-ratio: 3 / 2;
  display: grid;
  place-items: center;
  padding: 0.9rem;
  background: rgba(243, 244, 246, 0.85);
  border-bottom: 1px solid var(--tt-border);
}
.tt-nw-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* ---------- Body ---------- */
.tt-nw-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 1.25rem 1.4rem 1.5rem;
}

.tt-nw-tag {
  display: inline-block;
  align-self: flex-start;
  padding: 0.26rem 0.75rem;
  margin-bottom: 0.7rem;
  border-radius: 999px;
  background: rgba(var(--tt-primary-rgb), 0.1);
  border: 1px solid rgba(var(--tt-primary-rgb), 0.22);
  color: var(--tt-primary);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.tt-nw-title {
  font-family: var(--tt-font-poppins, var(--tt-font-primary));
  font-size: var(--tt-fs-h4);
  font-weight: 700;
  color: var(--tt-dark);
  margin: 0 0 0.6rem;
  line-height: 1.3;
}

.tt-nw-text {
  font-size: var(--tt-fs-body-sm);
  line-height: 1.75;
  color: var(--tt-muted);
  margin: 0 0 1.35rem;
}

.tt-nw-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  margin-top: auto;
  padding: 0.65rem 1.5rem;
  border-radius: 999px;
  background: var(--tt-gradient-primary);
  color: #fff;
  font-size: var(--tt-fs-body-sm);
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 10px 24px -12px rgba(var(--tt-primary-rgb), 0.8);
  transition: var(--tt-transition-standard);
}
.tt-nw-cta:hover {
  color: #fff;
  filter: brightness(1.06);
  transform: translateY(-1px);
}

/* ==================================================================
   RESPONSIVE
   ================================================================== */
@media (max-width: 767.98px) {
  .tt-nw-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 575.98px) {
  .tt-nw-cta { width: 100%; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .tt-nw-card, .tt-nw-cta { transition: none; }
  .tt-nw-card:hover, .tt-nw-cta:hover { transform: none; }
}
