/* ==========================================================================
   NEXT GEO — page stylesheet for the PRODUCTS HUB PAIR
     TR  22920  /urunler/      EN  25688  /en/products/
   One authored sheet for both; ng-page-apply.php --css-from copies it to
   products.css so the pair cannot drift.

   Loads last:
     ng-foundation → ng-components → ng-mobile → ng-shared → THIS FILE
   so a rule here at equal specificity beats all four. Anything below that a
   product LEAF page could reuse belongs in ng-shared.css instead — check there
   before adding. (Nothing here qualified: every block is specific to a hub
   that has to reconcile nine things of four different kinds.)

   ---------------------------------------------------------------------------
   WHAT WAS ACTUALLY WRONG, MEASURED

   ng-page-check on the live page, before this pass, at 1440 and 390:

       1440  44.6% dead air in 2 bands   h1 count 2   84 words rendered
        390  54.6% dead air in 2 bands   h1 count 2   70 words rendered
        390  8 tap targets under 44px (190x22, 209x22, 215x22 … icon-box titles)

   The dead air is not a spacing problem. `curl` returns 11 elements carrying
   `elementor-invisible`, and LiteSpeed runs optm-js_defer=2 — ~63 scripts sit
   on data-src and Elementor's animation script is one of them. So the h1, all
   seven product boxes, the closing heading and the closing BUTTON never became
   visible. What a real visitor saw was: a full-bleed stock 3D-city banner, a
   1600px void, one orphan grey sentence on a purple gradient, and the footer.
   Nothing on this page uses Elementor's animation stack any more; the reveal
   is the mu-plugin's single inline script, which carries data-no-defer and
   shows everything unconditionally after 2.5s.

   The h1 count of 2 was the theme's page-title banner, switched off at source
   (page_title_status = off) rather than hidden — hidden still counts.

   ---------------------------------------------------------------------------
   WHAT THIS PAGE IS FOR, AND THE THREE DECISIONS THAT FOLLOW

   1. NINE CARDS, NOT SEVEN — and grouped, not flat. GeoBrain and the WhatsApp
      Lokasyon Raporu exist on this site only as homepage sections; a product
      hub that omits two of the company's products is not a hub. They are here,
      tagged KATMAN and KANAL rather than ÜRÜN, and each resolves to the
      product it is genuinely part of. Nothing is invented for them: no page,
      no feature list, no screenshot. Their pills are the field names from the
      homepage's own labelled-illustrative sample output, and the note under
      the grid says so in plain Turkish.

      The grouping — platform / output and publishing / infrastructure and
      custom build — exists because the old page put a web platform, a PDF, a
      public map widget and a deployment service in one undifferentiated row of
      seven. Three groups of three is also exactly three full rows at >=960.

   2. THE CARD CARRIES THE CLIENT'S OWN LIST. Each of the seven cards with a
      product page prints that page's own capability block verbatim — 36 items
      in total. The old card printed `description_text`, which is the child
      page's headline and first paragraph run together and cut mid-sentence
      with an ellipsis; all seven therefore read as the same marketing
      fragment. The list is what makes GeoView distinguishable from Adres
      Çözümleri without opening either.

   3. THE PAGE ANSWERS "WHICH ONE IS FOR ME?" Section 30 is a need → product
      map, nine rows, every left-hand sentence assembled only from that
      product's own feature names. No page on this site did that before. It
      links to the CARDS on this page rather than to the child pages, so the
      hub does not ship two links to one URL with near-identical labels.

   THE PAGE IS ALSO A NAV-ORPHAN: the "Ürünler" mega-menu label is "#", it is
   in no footer menu and has zero inbound content links, so every visitor
   arrives from a child breadcrumb or from search. Hence its own .ng-crumbs,
   and hence the lateral chips out to /cozumler/ and /sektorler/ — a hub that
   only points down its own tree strands the person who has read all nine.
   ========================================================================== */


/* ==========================================================================
   1. MASTHEAD — copy left, a REAL SCREENSHOT right
   ========================================================================== */

/* 55/45 rather than ng-shared's 58/42. The aside here is not a chip list, it
   is a dense product capture (1084x610 of map, markers and chart panels); at
   42% it rendered ~450px wide and the interface stopped reading as an
   interface. 45% buys ~485px, which is where the drawn analysis area and the
   "Çalışan Sayısı 39.686" panel are still identifiable. Anything wider starts
   pushing the h1 measure under 18ch and the headline breaks badly in Turkish. */
@media (min-width:960px){
  .ng-v2 .ng-urunmh .ng-masthead__inner{
    grid-template-columns:minmax(0,55fr) minmax(0,45fr);
  }
}

/* The aside holds two things stacked: the capture, then the name index.
   The index is here rather than nowhere because of a measurement the automated
   check CANNOT make: at 1440 the aside originally ended at the figcaption and
   left ~350px of empty right column beside the proof strip. ng-page-check
   scores that 0% dead air — its occupancy sampler marks a row as painted if
   ANY element paints in it, and .ng-section paints its own background across
   the full width, so a one-column hole is invisible to it. It is not invisible
   in a screenshot, which is the whole reason this project screenshots. */
.ng-v2 .ng-urunmh__aside{
  display:flex; flex-direction:column; gap:24px;
  min-width:0;
}
/* `figure` carries a 1em/40px UA margin that no reset in this stack removes,
   which at 390 is a 40px inset on the widest element on the page — i.e. the
   classic "why is the image narrower than everything else" bug. Explicit. */
.ng-v2 .ng-urunmh__fig{ margin:0; }
@media (min-width:960px){
  /* Pinned to the top of its track rather than stretched: the copy column is
     the taller child and a stretched aside would leave a tall band of white
     under the index. margin-top aligns the frame's top edge with the h1 rather
     than with the breadcrumb. */
  .ng-v2 .ng-urunmh__aside{ align-self:start; margin-top:34px; }
}

/* Raised surface: white, hairline, soft shadow — the same role as .ng-card,
   because this frame holds content and sits on the ground. overflow:clip so
   the screenshot's own square corners take the frame's radius; `clip` and not
   `hidden` because `hidden` on an element in a grid track creates a scroll
   container that swallows the focus ring of anything inside it. */
.ng-v2 .ng-urunmh__frame{
  border:1px solid var(--ng-hairline);
  border-radius:var(--ng-radius);
  background:var(--ng-surface);
  box-shadow:var(--ng-shadow-card);
  overflow:clip;
  line-height:0;                      /* kills the inline-image descender gap */
}
.ng-v2 .ng-urunmh__img{
  display:block; width:100%; height:auto;
}

/* The caption does two jobs and both are deliberate: it names what is on
   screen, and it states that this is a capture of the product rather than an
   illustration. The homepage learned this the hard way — two generated
   rasters were read as screenshots and had to be replaced with DOM. 14px is
   the reading floor; this is a sentence, not a tracked label. */
.ng-v2 .ng-urunmh__cap{
  margin:12px 0 0;
  font-size:14px; line-height:1.55;
  color:var(--ng-muted);              /* 6.01:1 on ground */
}

/* The proof strip's footnote, held short of the full column measure so it
   does not start competing with the lede above it. */
.ng-v2 .ng-urunmh__note{ max-width:58ch; }


/* --- the name index -------------------------------------------------------
   A SUNKEN panel: mist + hairline, holding white chrome (the nine pills). It
   was first built flat on the ground with only a hairline rule above it and it
   read as a stray paragraph of links hanging off the bottom of the capture —
   the same finding that produced the homepage's sector panel and the sectors
   hub's index. The hairline is the load-bearing part: an untethered tint on a
   #FAFBFF ground reads as a smudge rather than as a plate. No shadow, because
   a recessed surface that also floats is a contradiction.

   ORDER IS PAGE ORDER, not alphabetical. The grid below is grouped by what the
   thing does, so an alphabetical index would send a visitor to card 7, then
   card 2, then card 9. The sectors hub sorts its index alphabetically for the
   opposite reason: its grid is alphabetical too. The index and the grid must
   agree; which order they agree on is the grid's decision. */
.ng-v2 .ng-urunidx{
  padding:22px 20px;
  background:var(--ng-surface-sunken);
  border:1px solid var(--ng-hairline);
  border-radius:var(--ng-radius);
}
.ng-v2 .ng-urunidx__label{ margin:0 0 14px; }

/* A wrap ROW at every width, not a two-column list. Nine chips whose Turkish
   names run to 24 characters wrap to five rows inside the 45% aside and to
   about the same on a phone — the same shape at both ends, and roughly half
   the height a 2x5 list would cost on mobile. */
.ng-v2 .ng-urunidx__list{
  list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:8px;
}
.ng-v2 .ng-urunidx__note{
  margin:16px 0 0;
  font-size:14px; line-height:1.55;
  color:var(--ng-muted);              /* 5.42:1 on mist */
}

/* The tenth row of the index, and the reason it is a ROW rather than a link
   inside the note above it: a visitor whose need is not one of the nine is the
   one person on this page with nowhere to go, and burying their route mid-
   sentence hides it. The sectors hub measured its equivalent at 282x42 as an
   inline link — a sub-44px tap target that cannot be grown without breaking
   the line box. As its own row it is 44px by construction, and the hairline
   above it says "this is not a product". */
.ng-v2 .ng-urunidx__ask{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  min-height:44px;
  margin-top:14px; padding-top:14px;
  border-top:1px solid var(--ng-hairline);
  font-family:var(--ng-font-display); font-weight:600;
  font-size:15px; line-height:1.3;
  color:var(--ng-accent);             /* 4.92:1 on mist */
  text-decoration:none;
}
@media (any-hover:hover){
  .ng-v2 .ng-urunidx__ask:hover .ng-arrow{ transform:translate3d(4px,0,0); }
}


/* ==========================================================================
   2. THE THREE GROUPS
   ========================================================================== */

.ng-v2 .ng-urungrp + .ng-urungrp{ margin-top:44px; }

/* Label and description on one line at desktop, wrapping to two below, over a
   hairline rule. The rule is what makes three groups read as three chapters
   rather than as nine cards with two stray sentences in them; it was built
   first without one and the middle group's header floated. */
.ng-v2 .ng-urungrp__head{
  display:flex; flex-wrap:wrap; align-items:baseline;
  gap:6px 20px;
  margin:0 0 18px;
  padding-bottom:14px;
  border-bottom:1px solid var(--ng-hairline);
}

/* An h3 wearing the eyebrow's clothes. It is a real heading — it is the only
   thing naming the three groups in the outline — but visually it is a chapter
   label, so it takes the eyebrow's face, tracking and colour rather than a
   heading size that would compete with the section h2 above it.
   13px is legal here and only here: letter-spacing is 0.08em, which is the
   tracked-label exception in the contract.
   (0,3,0) via the doubled class — the theme's
   `body .content-wrapper h3:not(:first-child){margin-top:50px}` is (0,2,2) and
   loads after us. See ng-shared.css §11; this is that list, extended. */
.ng-v2 .ng-urungrp__label.ng-urungrp__label{
  margin:0;
  font-family:var(--ng-font-label); font-weight:600;
  font-size:13px; line-height:1.2; letter-spacing:.08em;
  padding-right:.08em;                /* absorb the trailing letter-space */
  text-transform:none;                /* authored uppercase: uppercase maps
                                         i->I, so "GELİŞTİRME" would come back
                                         as "GELISTIRME" */
  color:var(--ng-accent);             /* 5.45:1 on ground */
  flex:0 0 auto;
}
.ng-v2 .ng-urungrp__desc{
  margin:0;
  font-size:15px; line-height:1.55;
  color:var(--ng-muted);
  max-width:70ch;
}


/* ==========================================================================
   3. THE NINE CARDS
   ========================================================================== */

/* scroll-margin, not scroll-padding on the root: the theme header is sticky at
   ~90px desktop / ~70px mobile, and without this every chooser row in section
   30 lands its card under the bar. Measured against the rendered header, the
   same values the sectors hub arrived at. */
.ng-v2 .ng-urunlist__cell{ scroll-margin-top:104px; }
@media (max-width:1364px){
  .ng-v2 .ng-urunlist__cell{ scroll-margin-top:84px; }
}

/* :target — the chooser row that brought you here should show you where you
   landed. An accent hairline and nothing else; a fill would survive a back
   navigation and read as a selection the visitor cannot clear. */
.ng-v2 .ng-urunlist__cell:target .ng-card{ border-color:var(--ng-accent); }

/* Icon chip left, kind tag right. The tag is the whole reason this row exists:
   two of the nine cards are NOT products, and a visitor has to be able to see
   that at a glance rather than discover it in the note under the grid. */
.ng-v2 .ng-urun__top{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; width:100%;
}

/* 12px with 0.1em tracking — the tracked-label exception, same as
   .ng-card__meta, and it is glanced at rather than read. Mist ground so it
   sits quietly next to the accent icon chip and does not read as a second
   affordance. */
.ng-v2 .ng-urun__tag{
  flex:0 0 auto;
  font-family:var(--ng-font-label); font-weight:600;
  font-size:12px; line-height:1.35; letter-spacing:.1em;
  text-transform:none;
  color:var(--ng-muted);              /* 5.42:1 on mist */
  background:var(--ng-surface-sunken);
  border-radius:var(--ng-radius-pill);
  padding:5px 11px 5px calc(11px + .1em);
}
/* KATMAN / KANAL. Accent on accent-wash measures 4.87:1 — over AA — and it is
   the one place on the page where the wash is used as a ground for text.
   Rejected alternative: a dashed card border for the two modules. It read as
   "unfinished" rather than "different kind of thing", which is exactly the
   wrong message for two products the company actually sells. */
.ng-v2 .ng-urun__tag--mod{
  color:var(--ng-accent);
  background:var(--ng-accent-wash);
}

/* Three lines reserved. The nine bodies run 76-140 characters, which is 2-3
   lines in a ~300px card column; without a floor the short cards (WhatsApp,
   at 76) pulled their meta rule up and the row lost its horizontal rhythm.
   A floor, not a cap — a longer body is allowed a fourth line. */
@media (min-width:620px){
  .ng-v2 .ng-urun__body{ min-height:4.8em; }
}

/* The hairline that separates the card's prose half from its data half. The
   meta above it says what the pills below it ARE, and it differs per card
   ("5 YETENEK BAŞLIĞI" / "6 RAPOR BÖLÜMÜ" / "4 ADIM" / "ÇIKTI ALANLARI"), so
   the one small label on the card carries information instead of being the
   ninth repetition of a single word. */
.ng-v2 .ng-urun__meta{
  margin-top:20px;
  padding-top:16px;
  border-top:1px solid var(--ng-hairline);
}
.ng-v2 .ng-urun__pills{ margin-top:10px; }

/* The honesty note. 92ch because it is three sentences of explanation and
   breaking it to 70ch made it four short ragged lines under a 1120px grid. */
.ng-v2 .ng-urunlist__note{
  margin-top:32px;
  max-width:92ch;
}


/* ==========================================================================
   4. THE CHOOSER — need on the left, product on the right
   ========================================================================== */

.ng-v2 .ng-secim__list{
  list-style:none; margin:0; padding:0;
  display:grid; gap:10px;
}

/* One full-width row per need rather than a two-column grid of nine. Both were
   built. In two columns the left-hand sentences (44-64 characters) wrapped to
   two lines and the product names collided with them at 960-1100px, and the
   reading order stopped being obvious — a decision table is read straight
   down. Full width also lets the row keep the shape it is imitating: a
   question, a gap, an answer.

   WHITE ON THE MIST BAND. This is the sunken surface doing its job — sunken
   holds white chrome, it never holds bare text. A row with no fill on the mist
   would be a list of links on a tinted rectangle, which is the treatment the
   old page used for its cards and is why it read as unstyled. */
.ng-v2 .ng-secim__link{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px 24px;
  min-height:64px;
  padding:14px 20px;
  background:var(--ng-surface);
  border:1px solid var(--ng-hairline);
  border-radius:var(--ng-radius-sm);
  text-decoration:none;
  transition:border-color .16s cubic-bezier(.25,.46,.45,.94),
             box-shadow .16s cubic-bezier(.25,.46,.45,.94);
}
@media (any-hover:hover){
  /* any-hover only: on a touch screen :hover sticks after the tap and leaves
     the row highlighted until the user taps elsewhere. */
  .ng-v2 .ng-secim__link:hover{
    border-color:var(--ng-border-strong);
    box-shadow:var(--ng-shadow-card);
  }
  .ng-v2 .ng-secim__link:hover .ng-arrow{ transform:translate3d(4px,0,0); }
}
.ng-v2 .ng-secim__link:focus-visible{ border-color:var(--ng-border-strong); }

/* 16px ink, not 15px muted. This is the sentence the visitor is scanning for
   themselves — it is the most-read text in this band — so it takes the body
   size and the full-contrast ink (14.95:1 on white). The muted role is for
   supporting copy, and nothing here is supporting. */
.ng-v2 .ng-secim__need{
  font-size:16px; line-height:1.45;
  color:var(--ng-ink);
  min-width:0;
}
.ng-v2 .ng-secim__to{
  display:inline-flex; align-items:center; gap:.45em;
  flex:0 0 auto;
  font-family:var(--ng-font-display); font-weight:600;
  font-size:15px; line-height:1.3;
  color:var(--ng-accent);             /* 5.64:1 on white */
  text-align:right;
}


/* ==========================================================================
   5. DEPLOYMENT MODELS — the third proof-strip number, shown
   ========================================================================== */

.ng-v2 .ng-kurulum{
  margin-top:36px;
  padding-top:30px;
  border-top:1px solid var(--ng-hairline);
}
/* Same eyebrow-as-heading treatment as .ng-urungrp__label, and doubled for the
   same (0,2,2) theme margin rule. Kept identical rather than factored into a
   shared class: they are two different components that happen to agree today,
   and a shared class would make a future change to one silently change the
   other. */
.ng-v2 .ng-kurulum__label.ng-kurulum__label{
  margin:0 0 16px;
  font-family:var(--ng-font-label); font-weight:600;
  font-size:13px; line-height:1.2; letter-spacing:.08em;
  padding-right:.08em;
  text-transform:none;
  color:var(--ng-accent);             /* 4.92:1 on mist */
}
.ng-v2 .ng-kurulum__grid{
  display:grid; grid-template-columns:minmax(0,1fr); gap:16px;
}
@media (min-width:620px){
  .ng-v2 .ng-kurulum__grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
/* Raised tiles, because this band is sunken. No shadow lift on hover: they are
   not links and never become one — there is no /kurulum-modelleri/ page, and
   inventing an affordance that leads nowhere is worse than a plain tile. */
.ng-v2 .ng-kurulum__tile{
  padding:20px 22px;
  background:var(--ng-surface);
  border:1px solid var(--ng-hairline);
  border-radius:var(--ng-radius);
}
.ng-v2 .ng-kurulum__name{
  margin:0;
  font-family:var(--ng-font-display); font-weight:600;
  font-size:19px; line-height:1.3;
  color:var(--ng-ink);
}
.ng-v2 .ng-kurulum__body{
  margin:8px 0 0;
  font-size:15px; line-height:1.6;
  color:var(--ng-muted);              /* 6.21:1 on white */
}
/* The client's own sentence about the two models, plus where it is published.
   NOT hyperlinked: an inline link inside a footnote measured 282x42 on the
   sectors hub — a sub-44px tap target that cannot be grown without breaking
   the line box — and the same product page is already one card and one chooser
   row away. */
.ng-v2 .ng-kurulum__note{ max-width:86ch; }


/* ==========================================================================
   6. LATERAL LINKS
   A hub must not only point down. These three are the only links on the page
   that leave the products tree, and they are chips rather than a sentence for
   the same tap-target reason as above — .ng-btn--pill is already 44px at
   mobile via ng-shared.css §12.
   ========================================================================== */
.ng-v2 .ng-urunlat{
  margin-top:34px;
  padding-top:26px;
  border-top:1px solid var(--ng-hairline);
}
.ng-v2 .ng-urunlat__label{ margin:0 0 14px; }
.ng-v2 .ng-urunlat__list{ margin-top:0; }


/* ==========================================================================
   7. RESPONSIVE
   The grids themselves are ng-shared's .ng-grid--3: 1 column below 620, 2 to
   960, 3 above. Three groups of three therefore land as 3x3 at desktop, 3x(2+1)
   at tablet and 9 stacked on a phone — no group ever ends on a hole, because
   every group is exactly one desktop row.
   ========================================================================== */

@media (max-width:959px){
  /* Stacked masthead. The aside goes UNDER the copy, not above it: the h1 and
     the lede are what a search visitor needs first, and a product capture
     between the breadcrumb and the headline pushes both below the fold on a
     phone. Source order already does this; this only tightens the gap the grid
     leaves. Stacked, the index lands directly under the three proof numbers,
     which is the right order — a visitor who has read the headline and the
     counts is exactly the person who then wants the list of nine. */
  .ng-v2 .ng-urunmh__aside{ margin-top:4px; }
}

@media (max-width:767px){
  /* Reading floor: everything below is a sentence, not a tracked label. */
  .ng-v2 .ng-urunmh__cap,
  .ng-v2 .ng-urungrp__desc,
  .ng-v2 .ng-kurulum__body{ font-size:16px; }
  .ng-v2 .ng-urunmh__note,
  .ng-v2 .ng-urunlist__note,
  .ng-v2 .ng-kurulum__note,
  .ng-v2 .ng-urunidx__note{ font-size:15px; }

  .ng-v2 .ng-urunidx{ padding:20px 16px; }
  .ng-v2 .ng-urunidx__list{ gap:8px 6px; }

  .ng-v2 .ng-urungrp + .ng-urungrp{ margin-top:34px; }
  .ng-v2 .ng-urun__meta{ margin-top:18px; padding-top:14px; }

  /* The chooser row stacks. Side-by-side at 390 gave the need 190px and the
     product name 120px, so "WhatsApp Lokasyon Raporu" took three lines in a
     column of its own while the sentence beside it took four — two ragged
     blocks of unequal height in every row. Stacked, the row is a sentence with
     its answer under it, and the whole 44px+ block is one tap target. */
  .ng-v2 .ng-secim__link{
    flex-direction:column; align-items:flex-start;
    gap:8px;
    min-height:44px;
    padding:14px 16px;
  }
  .ng-v2 .ng-secim__to{ text-align:left; }
  .ng-v2 .ng-kurulum__tile{ padding:18px 16px; }
  .ng-v2 .ng-kurulum{ margin-top:30px; padding-top:26px; }
  .ng-v2 .ng-urunlat{ margin-top:28px; padding-top:22px; }
}


/* ==========================================================================
   8. REDUCED MOTION
   ng-shared.css §10 already flattens .ng-card and .ng-arrow under a reduce
   preference — including cancelling ng-components.css's !important marker
   transform. The only motion this page adds beyond that is the chooser row's
   border/shadow transition, which is a colour change and not movement, and the
   arrow inside it, which §10 already pins. Left as a note rather than an empty
   block so the next person does not go looking for a missing rule.
   ========================================================================== */
