/* =============================================================================
   Opsy website — the OpsyOne & OpsyGO view.

   Same rules as css/site.css: flat plain CSS, kit tokens, the `op-` prefix.
   Loaded after css/home.css, which this view needs as well: its opening, its
   section intro, its closing panel and every drawing live there.
   Layout follows the user's three images of 2026-10-05; the copy is the
   brief's, verbatim. The page itself is written in the site repo
   (src/pages/products.njk): this file is its source, copied across by
   scripts/sync-site.mjs.
   Spec: docs/specs/2026-10-05-website-opsyone-opsygo-page.md
   ========================================================================== */

/* --- A weight of the website's own ------------------------------------------- */
/* Poppins Bold. The kit ships the family at 400, 500 and 600 (kit/fonts.css);
   the price's sum is set a weight heavier, as the brief has it, on the user's
   word. So this one file is the website's own -- assets/fonts/, not the
   generated fonts/ -- and the kit is not changed. The Latin subset from
   Google Fonts (Poppins v24, SIL Open Font Licence), declared as the kit
   declares its faces. A browser fetches it only where the weight is used. */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/poppins-700.woff2') format('woff2');
}

/* --- Opening ---------------------------------------------------------------- */
/* The opening every page but the home page has (css/home.css, Opening), and
   what this page adds to it: a second line under the headline, and an action.
   The gaps grow down the block as the breaks in meaning do: 16px from the
   headline to its second line, 24px to the lead, 32px to the action, 64px to
   the two products' block, which opens with their pictures. Each is the
   borrowed column's own 16px gap plus what a rule adds. */
/* The headline's second line, at the column's own gap. Its colour is the
   brief's. */
.op-opening__sub {
  color: var(--brand-primary);
}
/* 16px more than the column's gap; the home page's hero adds 8px. */
.op-opening .op-hero__actions {
  margin-top: var(--space-4);
}

/* --- The two products ---------------------------------------------------------- */
/* Each product is one unit and one row of the page: its picture on one side,
   and on the other its name with tagline and lead, then its three points. The
   second row is mirrored. A unit keeps a picture and the text about it
   together; before, the two pictures shared a panel and the two texts were
   stacked under it. The user's pick of three layouts compared by eye on the
   page -- the other two set a column per product under one shared panel, or
   under a panel each.
   No grey line anywhere in the block, the user's ruling: the two rows stand
   two near steps apart, and the points by their spacing alone.
   Spec: docs/specs/2026-10-05-website-opsyone-opsygo-page.md, Rev 3.

   The picture's share of the row is said once, --op-pic-share, and --op-pic
   is its width from it: the row less the gap, times the share. The columns
   and the connector both read it. Five twelfths, the split Built together
   has, below: the user's pick of three tried by eye (a half; a third, which
   left the text beside it too long a line). */
.op-products {
  --op-products-gap: calc(var(--space-8) * 2);
  --op-pic-share: calc(5 / 12);
  --op-pic: calc((100% - var(--op-products-gap)) * var(--op-pic-share));
  padding-bottom: var(--op-space-section);
}
.op-products .op-product {
  position: relative; /* the connector is placed by the first one's edges */
  display: grid;
  grid-template-columns: var(--op-pic) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  column-gap: var(--op-products-gap);
  align-items: start;
}
/* The picture stands beside the whole text, from the name to the last point. */
.op-products .op-product__frame {
  grid-area: 1 / 1 / 3 / 2;
}
.op-products .op-product__head {
  grid-area: 1 / 2;
}
/* 40px from the lead to the points. */
.op-products .op-points {
  grid-area: 2 / 2;
  margin-top: var(--space-10);
}
/* The second row: mirrored, two near steps under the first. The connector
   crosses in that gap. */
.op-products .op-product + .op-product {
  grid-template-columns: minmax(0, 1fr) var(--op-pic);
  margin-top: calc(var(--op-space-near) * 2);
}
.op-products .op-product + .op-product .op-product__frame {
  grid-column: 2;
}
.op-products .op-product + .op-product .op-product__head,
.op-products .op-product + .op-product .op-points {
  grid-column: 1;
}
/* The picture's panel is the offers' (css/home.css, .op-offer__media), on this
   page's mint where theirs is grey. A primitive, the closing panel's tone: the
   kit's only alias for this step names a hover. */
.op-product__media {
  --op-panel: var(--genoa-100);
}
.op-product__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.op-product__tagline {
  color: var(--brand-primary);
}
/* A lead: the secondary ink's one job (css/home.css, .op-hero__lead). 24px
   under the tagline: the head's own 8px gap and these 16px. (The tagline
   itself is the kit's 20px heading, a step above this 18px lead; it was the
   24px one and read too large under the name.) */
.op-product__lead {
  margin-top: var(--space-4);
  color: var(--text-secondary);
}

/* The connector: OpsyGO and OpsyOne as two steps of one process. A solid
   line straight down from the middle of the first picture's foot, across in
   the middle of the gap between the rows, and straight down onto the middle
   of the second picture's top. (Its first form was a dashed curve that bowed
   and swept; it read as uncertain.)
   Two boxes draw it, each two of its edges and the corner between them, so
   the runs stay straight and the corners round at any width and any length
   of text -- a stretched drawing would bend both. Both hang off the first
   product (the wrapper covers it):
     --down  from 16px under the picture to the middle of the gap, a near
             step under the product's foot: its left and bottom edges. The
             picture is two-thirds as tall as it is wide, and a percentage
             margin can say so, since a margin is measured on the width even
             down the page.
     --on    from there to 16px short of the second picture: its top and
             right edges. It starts a line's weight higher, so the two
             crossing edges lie on the same pixels.
   The two meet in the middle of the row and are equally wide; each reaches
   half the line's weight past its picture's middle, so the line itself is
   centred there.
   Its weight and its ink are said once, on the wrapper. The weight is the
   small drawings' outline, 2px (css/home.css, .op-spot), so the line and the
   marks beside it are drawn with one pen. The ink is light: the brand's own
   line colour, the mint those drawings fill with -- it links the two
   pictures without competing with them. (It was the drawings' dark connector
   teal at 1.5px first.) */
.op-products .op-products__path {
  --op-step-w: 2px;
  --op-step-ink: var(--brand-border);
  position: absolute;
  inset: 0;
  display: block;
  pointer-events: none;
}
.op-products__leg {
  position: absolute;
  width: calc(50% - var(--op-pic) / 2 + var(--op-step-w) / 2);
  border: 0 solid var(--op-step-ink);
}
.op-products__leg--down {
  top: 0;
  bottom: calc(var(--op-space-near) * -1);
  left: calc(var(--op-pic) / 2 - var(--op-step-w) / 2);
  margin-top: calc(var(--op-pic) * 2 / 3 + var(--space-4));
  border-width: 0 0 var(--op-step-w) var(--op-step-w);
  border-bottom-left-radius: calc(var(--radius-lg) * 2);
}
.op-products__leg--on {
  top: calc(100% + var(--op-space-near) - var(--op-step-w));
  left: 50%;
  height: calc(var(--op-space-near) - var(--space-4) + var(--op-step-w));
  border-width: var(--op-step-w) var(--op-step-w) 0 0;
  border-top-right-radius: calc(var(--radius-lg) * 2);
}
/* The dot the line starts from and the tip it ends in, each centred on the
   line: a part's inside begins a line's weight in from its drawn edge, so
   the line's middle is half a weight outside it. The dot is 8px across. The
   tip is a 10px square's two edges, turned; its point comes 7px under the
   square's middle, so the square sits 2px up for the point to rest on the
   line's end. */
.op-products__leg--down::before,
.op-products__leg--on::after {
  content: '';
  position: absolute;
}
.op-products__leg--down::before {
  top: -4px;
  left: calc(var(--op-step-w) / -2 - 4px);
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--op-step-ink);
}
.op-products__leg--on::after {
  right: calc(var(--op-step-w) / -2 - 5px);
  bottom: 2px;
  width: 10px;
  height: 10px;
  border-right: var(--op-step-w) solid var(--op-step-ink);
  border-bottom: var(--op-step-w) solid var(--op-step-ink);
  rotate: 45deg;
}

/* A point: a mark, a title and a text. A product's three points lead with a
   small drawing in the home page's reasons style (css/home.css, .op-spot);
   the price panel's two cases, with a bare mark. No line between neighbours:
   they stand apart by their spacing (spec, Rev 3). */
.op-points {
  display: flex;
  flex-direction: column;
}
.op-point {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--space-8);
  align-items: start;
  padding-block: var(--space-6);
}
.op-point:first-child {
  padding-top: 0;
}
.op-point:last-child {
  padding-bottom: 0;
}
/* In a reasons cell the drawing sits at the cell's far end; here it leads the
   row, level with the title. */
.op-point .op-spot {
  align-self: start;
}
/* 8px from title to text. The title's own line sits a little below the
   mark's top, so the two read as starting together: a drawing keeps about
   8px clear above its shapes, which is where the title's letters begin. */
.op-point__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-1);
}

/* The kinds of case a rådgivare is matched on: eight plain tags. The tag
   itself is shared with another page and lives in css/site.css (Tag). */
.op-kinds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* --- AI as support: a grey band ------------------------------------------------ */
/* The trust band's padding (css/home.css, .op-trust) on the lightest grey,
   where that band is mint: the user's ruling, after a picture they sent
   (spec, Rev 9). A primitive: the kit's alias for this tone names a hover.
   The source panel is then the one mint thing on the band. */
.op-ai {
  padding-block: calc(var(--space-9) * 2);
  background: var(--submarine-50);
}
.op-ai__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: calc(var(--space-8) * 2);
  align-items: start;
  margin-top: var(--op-space-intro);
}
/* Tabs (js/tabs.js): which of the two lists is shown. The control keeps its
   own width; the lists take the column's. */
.op-tabs {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-6);
}
/* The control is the kit's SegmentedControl in plain CSS, at its medium size
   (design-system/components/SegmentedControl): a recessed track a step deeper
   than the surface it sits on, 40px tall with a 4px inset, and a white thumb,
   lifted by the kit's small shadow, on the segment chosen. The band is grey,
   as the kit's own surfaces are, so the track is grey too, and the kit's own
   tone exactly: a primitive there as here. One step lighter was tried and
   read too pale: the user's ruling. (It was mint while the band was.) A segment's type is the kit's label-md, in the markup;
   its line is as tall as itself, so the label centres by the font's metrics.
   The look is read off aria-selected, so what is shown and what a screen
   reader announces cannot drift apart. (The two were a pair of Buttons, one
   solid, first.) */
.op-seg {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--submarine-300);
}
.op-seg__item {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Two short labels of unequal length: a shared minimum makes them a pair. */
  min-width: 120px;
  height: 32px;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  line-height: 32px;
  /* The body ink, where the kit's control has the secondary: on this track
     the secondary comes to 4.4:1, under the 4.5:1 a label this size needs. */
  color: var(--text-primary);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--motion-fast) var(--ease-standard),
    color var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard);
}
/* Hover previews the thumb: a half-formed one, as in the kit. */
.op-seg__item:hover {
  background: color-mix(in srgb, var(--white) 50%, transparent);
}
.op-seg__item[aria-selected='true'] {
  background: var(--surface-card);
  box-shadow: var(--shadow-sm);
  font-weight: 600;
  color: var(--brand-primary);
}
/* The kit's inset ring: it stays on the thumb, clear of the track's frame. */
.op-seg__item:focus-visible {
  outline-offset: -2px;
}
/* One height. Under the script both panels share one grid cell and the one
   not chosen is hidden but keeps its room, so the band is as tall as its
   longer list and the page below does not move when the choice changes.
   Without the script the second panel carries `hidden` and the first is all
   there is. */
.op-tabs__panels {
  align-self: stretch;
  display: grid;
}
.op-tabs.is-live .op-tabs__panel {
  grid-area: 1 / 1;
  visibility: hidden;
}
.op-tabs.is-live .op-tabs__panel.is-selected {
  visibility: visible;
}

/* A list of marked lines: a mark and a line of text. No disc behind the mark
   and no line between neighbours, the user's ruling for this section: the
   lines stand apart by their spacing. */
.op-marked {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.op-marked__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}
/* The mark, a tick or a cross, is drawn as the small drawings are: a 2px
   round-ended line in the brand's deep teal. The line is its mask's
   (drawings/pictures.html, the ico-...-mark frames); the colour is given
   here. 24px, the height of a line of the text beside it, so on a text of
   two lines it stands with the first. */
.op-marked__mark {
  width: 24px;
  height: 24px;
  color: var(--brand-primary);
}

/* The source reference, in the column a drawing stood in. No panel: it stands
   on the band, as the lists beside it do (it was one mint panel first; the
   user's ruling). A small drawing leads its heading; its first sentence is
   highlighted; the other two follow as a paragraph each. The three are the
   brief's one paragraph, broken at its sentence ends. */
.op-ai__source {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.op-ai__head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
/* The drawing, first in the heading's row and 48px tall: the user's placing
   and size. It has a render of its own at this size, its line brought up to
   1.6px, the least a drawing's line may be (drawings/art.css, Marks). In a
   reasons cell the drawing is set to the far end; here the row centres it on
   the heading. */
.op-ai__spot {
  align-self: center;
  width: calc(48px * 88 / 72);
  height: 48px;
}
/* The first sentence, highlighted as a number is on its chip (css/home.css,
   .op-stat__value): the same mint, the brand's deep teal on it, the same 8px
   corner -- a marker's stroke. At the size of the text around it, its type
   the kit's body style in the markup: the highlight is the fill and the ink,
   and one step of weight -- medium, the user's ruling of 2026-10-06, where it
   was the body's regular. Not a larger letter. The mint is a primitive, as
   on the chip. */
.op-ai__claim {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--genoa-100);
  color: var(--brand-primary);
  font-weight: 500;
}

/* --- Price ---------------------------------------------------------------------- */
/* Two columns: one mint panel with the price, its terms and the two cases on
   the left; the label, heading and two paragraphs on the right. After a
   picture the user sent (spec, Rev 7), and flipped on their word (Rev 9): the
   text stood on the left first. The flip is made here and not in the markup,
   where the text still comes first: a screen reader meets the heading before
   the price, and on a phone the heading stays above the panel. */
.op-price {
  padding-block: var(--op-space-section);
}
.op-price__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: calc(var(--space-8) * 2);
  align-items: center;
}
.op-price__grid .op-intro {
  grid-area: 1 / 2;
}
/* The panel's mint is the picture panels' (.op-product__media): a primitive,
   as there. */
.op-price__panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  padding: var(--space-8);
  border-radius: var(--radius-lg);
  background: var(--genoa-100);
}
/* The panel's first row: the price, and at its far end the terms. When the two
   do not fit side by side the terms go under the price. */
.op-price__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4) var(--space-6);
}
/* The price: the sum in the display style, and what it is for beside it on
   the same baseline. The brand's deep teal, as a number on its chip
   (css/home.css, .op-stat__value). */
.op-price__figure {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
  color: var(--brand-primary);
}
/* The sum alone is Bold: the website's own weight, at the top of this file. */
.op-price__sum {
  font-weight: 700;
}
/* The terms: two tags, one over the other, at the row's far end. The tags are
   the kinds of case's (.op-kind, with its type in the markup); those are this
   panel's own mint on a white page, so here the fill is one step deeper, to
   show on the panel -- a primitive; the kit's only alias for it names a
   border. The user's wording and placing: the brief has the two as one
   sentence, which stood here in one tag under the price first. */
.op-price__terms {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
}
.op-price__terms .op-kind {
  background: var(--genoa-200);
}
/* The two cases are the product points' row (A point, above), each led by a
   bare mark where a point has a drawing: a tick and an arrow, the lists'
   2px teal mark (.op-marked__mark). Drawings were tried here and were too
   large for a row this small: the user's ruling. A row is padded like a
   card, and the first, the case that is paid for, stands on white: the
   accent is that fill alone -- the user asked for an accent; no line, border
   or second colour was added for it. The other case is the same row, bare
   on the panel. */
.op-price__cases {
  gap: var(--space-2);
  margin-top: var(--space-6);
}
.op-price__cases .op-point {
  column-gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-md);
}
.op-price__cases .op-point:first-child {
  background: var(--surface-card);
}
/* A mark is a line of the title tall, so the title starts level with it: the
   4px a point's text drops beside a drawing is taken back. */
.op-price__cases .op-point__body {
  padding-top: 0;
}

/* --- How they fit together -------------------------------------------------------- */
/* One section: its title and two paragraphs (the section intro, css/home.css,
   .op-intro), then four cards, two by two, after the brief's own block of
   four: three points and the ticked list Varför välja Opsy. A card is a small
   drawing, a heading and the text -- the home page's offer card without its
   picture panel (css/home.css, .op-offer): the same column and the same
   steps, 24px from the drawing to the heading and 12px from the heading to
   the text. (They were three rows with a hairline between and the list a
   section of its own first: spec, Rev 11 to 13.) */
.op-together {
  padding-bottom: var(--op-space-section);
}
.op-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--space-8) * 2);
  margin-top: var(--op-space-intro);
}
/* In a reasons cell the drawing sits at the far end (css/home.css, .op-spot);
   here it leads the card. */
.op-cards .op-spot {
  align-self: flex-start;
}
/* The fourth card is the section's summary box: the ticked list on the price
   panel's mint, corner and padding (.op-price__panel). A grid stretches its
   cells, so the box is as tall as the card beside it -- which is what
   balances a list against a paragraph, the user's pick of three ways tried
   (spec, Rev 14). The box is its own mark and carries no drawing. */
.op-cards__box {
  padding: var(--space-8);
  border-radius: var(--radius-lg);
  background: var(--genoa-100);
}
/* Its ticked lines: the lists' own (.op-marked), a little closer, since a
   card is a smaller room than a column. */
.op-cards .op-marked {
  align-self: stretch;
  gap: var(--space-3);
  margin-top: var(--space-1);
}

/* --- Narrow ------------------------------------------------------------------------------ */
/* As on the home page: no phone design pass, the page only stacks sensibly. */
@media (max-width: 960px) {
  /* The two products: one stack, a product after the other, each its picture
     and then its text; the near step between the two. No connector. */
  .op-products .op-products__grid,
  .op-products .op-product,
  .op-products .op-product__head,
  .op-products .op-points {
    display: flex;
    flex-direction: column;
    /* Named, because the wide layout sets a row's parts to their own size: a
       picture's panel has no width of its own and would close to nothing. */
    align-items: stretch;
  }
  .op-products .op-product__head,
  .op-products .op-points {
    margin-top: var(--space-10);
  }
  .op-products .op-product + .op-product {
    margin-top: var(--op-space-near);
  }
  .op-products .op-products__path {
    display: none;
  }
  .op-ai__grid,
  .op-price__grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-10);
  }
  /* The price section in the markup's order again: the text, then the panel. */
  .op-price__grid .op-intro,
  .op-price__panel {
    grid-area: auto;
  }
  /* The four cards in one column. */
  .op-cards {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-10);
  }
  /* A picture alone in a column keeps a picture's width, on the left edge. */
  .op-product__frame {
    max-width: 560px;
  }
}
@media (max-width: 560px) {
  .op-point {
    column-gap: var(--space-4);
  }
  /* Three-quarters of its size, so the text beside it keeps its room. The
     outline thins with it, to 1.5px. */
  .op-point .op-spot {
    width: 66px;
    height: 54px;
  }
  /* The control takes the column's width, its two segments half each. */
  .op-seg {
    align-self: stretch;
    display: flex;
  }
  .op-seg__item {
    flex: 1;
    min-width: 0;
  }
  /* The two tags side by side under the price. */
  .op-price__terms {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
  }
  /* The price panel, its cases and the summary box, with a phone's padding. */
  .op-price__panel,
  .op-cards__box {
    padding: var(--space-5);
  }
  .op-price__cases .op-point {
    column-gap: var(--space-4);
    padding: var(--space-4);
  }
}
/* Under a finger (css/site.css, Narrow): on a touch screen the switch's two
   segments are 44px high, where a mouse has the kit's 32px. */
@media (hover: none) and (pointer: coarse) {
  .op-seg__item {
    height: 44px;
    line-height: 44px;
  }
}
