@soloworks/smking-next 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @soloworks/smking-next
2
2
 
3
+ ## 0.14.1 — 2026-05-23
4
+
5
+ **Carousel polish in canonical CSS — nav buttons, dots indicator, image-frame, caption-row + download icon now ship to customer Mode A pages.**
6
+
7
+ ### Added
8
+
9
+ - `packages/shared/src/styles/cms-styles.css` (regenerated into `SMKING_CMS_STYLES` const) now carries the full Apple-newsroom-style carousel CSS: container-query-anchored nav buttons (vertical centre tracks the image height across all 5 aspect ratios), per-slide `image-frame` with placeholder state, caption-row with download icon affordance, dots indicator with active state. Same rules the smking dashboard preview already used — bringing customer parity.
10
+ - Carousel works identically regardless of whether the Web Component IIFE has upgraded the markup: CSS positions everything relative to the `<smking-carousel>` container query, so static HTML renders just as well as the JS-upgraded interactive variant.
11
+
12
+ ### Pairs with
13
+
14
+ - `smking/laravel` v0.15.1 — same canonical CSS payload (identical sha256), Laravel `<x-smking-cms />` Mode A render picks up the polish automatically on view-cache clear.
15
+
16
+ ### Customer
17
+
18
+ ```bash
19
+ pnpm update @soloworks/smking-next # → 0.14.1
20
+ ```
21
+
22
+ No code change required. Existing `<SmkingCms>` Mode A renders get nav / dots / image-frame styling on the next page load.
23
+
3
24
  ## 0.14.0 — 2026-05-23
4
25
 
5
26
  **Single-source CSS distribution + theme mode toggle.** `<SmkingCms>` now ships its own polished default styles by default — no customer CSS work needed. Customers who already use Tailwind + `@tailwindcss/typography` can flip to a prose-utility markup variant via the `mode` prop or `SMKING_CMS_THEME` env var.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soloworks/smking-next",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "AI-native SEO (AEO) for Next.js — auto-inject JSON-LD, FAQ, AI summary, and SEO metadata so AI crawlers (ChatGPT, Perplexity, Google AI) can cite your pages.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/sillyleo/smking/tree/main/packages/smking-next",
@@ -2,7 +2,7 @@
2
2
  * AUTO-GENERATED - do not edit by hand.
3
3
  * Source: packages/shared/src/styles/cms-styles.css
4
4
  * Sync: pnpm sync:cms-styles
5
- * Hash: bf93aa1f4b52
5
+ * Hash: f555c5fed446
6
6
  *
7
7
  * Inlined by <SmkingCms> (smking-cms.tsx) inside a
8
8
  * <style data-smking="cms-styles"> ... </style>
@@ -493,70 +493,205 @@ export const SMKING_CMS_STYLES = `/*
493
493
  }
494
494
 
495
495
  /* ============================================================
496
- Carousel — \`data-aspect\` token-driven aspect-ratio
497
- SDK emits: \`<section class="smk-block smk-block--carousel smk-carousel"
498
- data-aspect="16:9|4:3|1:1|3:4|9:16">\`
499
- 5 aspect ratio variants — picked by the editor's settings popover,
500
- written into props.aspectRatio, surfaced as data-aspect attr by
501
- SDK render. All variant CSS lives below — image / slide both consume
502
- the same --smk-carousel-aspect token.
496
+ Carousel — Apple-newsroom style horizontal carousel with
497
+ \`data-aspect\` token-driven aspect-ratio, container-query-anchored
498
+ nav buttons, and dots indicator.
499
+ SDK emits:
500
+ <smking-carousel class="smk-block smk-block--carousel smk-carousel"
501
+ data-aspect="16:9|4:3|1:1|3:4|9:16">
502
+ <div class="smk-carousel__viewport">
503
+ <smking-slide>
504
+ <div class="smk-carousel__image-frame">
505
+ <img class="smk-carousel__image" /> or .__image--placeholder
506
+ </div>
507
+ <div class="smk-carousel__caption-row">
508
+ <div class="smk-carousel__caption">…</div>
509
+ <a class="smk-carousel__download" href />
510
+ </div>
511
+ </smking-slide>
512
+ </div>
513
+ <button class="smk-carousel__nav-prev|next" />
514
+ <div class="smk-carousel__dots">
515
+ <button class="smk-carousel__dot" aria-current="true|false" />
516
+ </div>
517
+ </smking-carousel>
518
+
519
+ Web Component IIFE (SMKING_ELEMENTS_IIFE) upgrades the markup with
520
+ swipe / scroll-snap / dot-binding behaviour client-side. CSS below
521
+ drives all visual state — image cover-fill, nav-button vertical
522
+ centering anchored to image height (cqw container-queries), dot
523
+ active state.
503
524
  ============================================================ */
525
+ smking-carousel,
504
526
  .smk-carousel {
527
+ display: block;
528
+ position: relative;
505
529
  margin: 2.5rem 0;
530
+ padding-top: 2.5rem; /* room for editor settings overlay; harmless on customer side */
531
+ padding-bottom: 1.5rem;
532
+ container-type: inline-size; /* enables \`cqw\` for nav-button vertical anchor */
506
533
  --smk-carousel-aspect: 16 / 9;
534
+ --smk-carousel-nav-top: 28.125cqw; /* 50cqw × 9/16 = half of image height */
507
535
  }
508
- .smk-carousel[data-aspect="4:3"] {
536
+ .smk-carousel[data-aspect="4:3"],
537
+ smking-carousel[data-aspect="4:3"] {
509
538
  --smk-carousel-aspect: 4 / 3;
539
+ --smk-carousel-nav-top: 37.5cqw;
510
540
  }
511
- .smk-carousel[data-aspect="1:1"] {
541
+ .smk-carousel[data-aspect="1:1"],
542
+ smking-carousel[data-aspect="1:1"] {
512
543
  --smk-carousel-aspect: 1 / 1;
544
+ --smk-carousel-nav-top: 50cqw;
513
545
  }
514
- .smk-carousel[data-aspect="3:4"] {
546
+ .smk-carousel[data-aspect="3:4"],
547
+ smking-carousel[data-aspect="3:4"] {
515
548
  --smk-carousel-aspect: 3 / 4;
549
+ --smk-carousel-nav-top: 66.667cqw;
516
550
  }
517
- .smk-carousel[data-aspect="9:16"] {
551
+ .smk-carousel[data-aspect="9:16"],
552
+ smking-carousel[data-aspect="9:16"] {
518
553
  --smk-carousel-aspect: 9 / 16;
554
+ --smk-carousel-nav-top: 88.889cqw;
519
555
  }
556
+
520
557
  .smk-carousel__viewport {
521
- display: grid;
522
- grid-auto-flow: column;
523
- grid-auto-columns: 80%;
524
- gap: 1rem;
558
+ display: flex;
525
559
  overflow-x: auto;
526
560
  scroll-snap-type: x mandatory;
561
+ scroll-behavior: smooth;
562
+ scrollbar-width: none;
527
563
  -webkit-overflow-scrolling: touch;
528
- padding-bottom: 0.5rem;
529
- margin-inline: -1.5rem;
530
- padding-inline: 1.5rem;
531
- }
532
- @media (min-width: 640px) {
533
- .smk-carousel__viewport {
534
- grid-auto-columns: 60%;
535
- }
536
564
  }
537
565
  .smk-carousel__viewport::-webkit-scrollbar {
538
- height: 6px;
539
- }
540
- .smk-carousel__viewport::-webkit-scrollbar-thumb {
541
- background: var(--smk-border-strong);
542
- border-radius: 3px;
566
+ display: none;
543
567
  }
568
+
569
+ smking-slide,
544
570
  .smk-carousel__slide {
571
+ display: flex;
572
+ flex-direction: column;
573
+ flex: 0 0 100%;
545
574
  scroll-snap-align: start;
546
- background: var(--smk-bg-soft);
547
- border-radius: var(--smk-radius-md);
575
+ min-width: 0;
576
+ padding-inline: 0.5rem;
577
+ gap: 1rem;
578
+ }
579
+
580
+ /* Image frame — fixed-aspect box. Image cover-fills. */
581
+ .smk-carousel__image-frame {
582
+ position: relative;
583
+ aspect-ratio: var(--smk-carousel-aspect);
548
584
  overflow: hidden;
585
+ border-radius: var(--smk-radius-md);
549
586
  }
550
587
  .smk-carousel__image {
588
+ display: block;
551
589
  width: 100%;
552
- aspect-ratio: var(--smk-carousel-aspect);
590
+ height: 100%;
553
591
  object-fit: cover;
554
- display: block;
592
+ }
593
+ .smk-carousel__image--placeholder {
594
+ width: 100%;
595
+ height: 100%;
596
+ display: flex;
597
+ align-items: center;
598
+ justify-content: center;
599
+ background: var(--smk-bg-soft);
600
+ border: 1px dashed var(--smk-border);
601
+ }
602
+
603
+ /* Caption row — text on the left, download icon on the right. Matches
604
+ Apple newsroom's per-slide attribution + asset-download pattern. */
605
+ .smk-carousel__caption-row {
606
+ display: flex;
607
+ align-items: center;
608
+ justify-content: space-between;
609
+ gap: 1rem;
610
+ padding-inline: 0.25rem;
555
611
  }
556
612
  .smk-carousel__caption {
557
- padding: 0.75rem 1rem;
613
+ flex: 1;
614
+ text-align: center;
558
615
  font-size: 0.875rem;
559
616
  color: var(--smk-fg-muted);
617
+ line-height: 1.5;
618
+ }
619
+ .smk-carousel__download {
620
+ display: inline-flex;
621
+ align-items: center;
622
+ justify-content: center;
623
+ width: 1.75rem;
624
+ height: 1.75rem;
625
+ border-radius: 9999px;
626
+ color: var(--smk-fg-muted);
627
+ text-decoration: none;
628
+ transition: background-color 0.15s, color 0.15s;
629
+ }
630
+ .smk-carousel__download:hover {
631
+ background: var(--smk-bg-soft);
632
+ color: var(--smk-fg);
633
+ }
634
+
635
+ /* Nav buttons — circular cards overlapping the image edges. Top is
636
+ centered on the IMAGE (not the whole carousel) via container query:
637
+ image height = 100cqw × (ratio_h / ratio_w); half = nav-top var.
638
+ 2.5rem offset = container padding-top. */
639
+ .smk-carousel__nav-prev,
640
+ .smk-carousel__nav-next {
641
+ position: absolute;
642
+ top: calc(2.5rem + var(--smk-carousel-nav-top));
643
+ transform: translateY(-50%);
644
+ z-index: 1;
645
+ display: inline-flex;
646
+ align-items: center;
647
+ justify-content: center;
648
+ width: 2.5rem;
649
+ height: 2.5rem;
650
+ padding: 0;
651
+ border-radius: 9999px;
652
+ border: 1px solid var(--smk-border);
653
+ background: var(--smk-bg);
654
+ color: var(--smk-fg);
655
+ cursor: pointer;
656
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);
657
+ transition: background-color 0.15s, transform 0.15s;
658
+ }
659
+ .smk-carousel__nav-prev { left: 0.75rem; }
660
+ .smk-carousel__nav-next { right: 0.75rem; }
661
+ .smk-carousel__nav-prev:hover,
662
+ .smk-carousel__nav-next:hover {
663
+ background: var(--smk-bg-soft);
664
+ }
665
+ .smk-carousel__nav-prev:active,
666
+ .smk-carousel__nav-next:active {
667
+ transform: translateY(-50%) scale(0.95);
668
+ }
669
+
670
+ /* Dots — small circles centered below the caption row. Inactive is
671
+ hairline grey, active fills with foreground colour. */
672
+ .smk-carousel__dots {
673
+ display: flex;
674
+ justify-content: center;
675
+ align-items: center;
676
+ gap: 0.5rem;
677
+ margin-top: 0.75rem;
678
+ }
679
+ .smk-carousel__dot {
680
+ width: 0.5rem;
681
+ height: 0.5rem;
682
+ padding: 0;
683
+ border-radius: 9999px;
684
+ border: none;
685
+ background: color-mix(in srgb, var(--smk-fg) 20%, transparent);
686
+ cursor: pointer;
687
+ transition: background-color 0.15s, transform 0.15s;
688
+ }
689
+ .smk-carousel__dot:hover {
690
+ background: color-mix(in srgb, var(--smk-fg) 45%, transparent);
691
+ }
692
+ .smk-carousel__dot[aria-current="true"] {
693
+ background: var(--smk-fg);
694
+ transform: scale(1.1);
560
695
  }
561
696
 
562
697
  /* ============================================================