# Social Sharing Widget — Design Spec

**Date:** 2026-04-17  
**Status:** Approved  
**Scope:** New partial + integration into sidebar and repository page

---

## Problem

The site has i18n keys for sharing (`share`, `copyLink`, `twitter`, `facebook`) but no implemented sharing UI. Users have no in-page way to share content on social platforms.

## Goal

A reusable, icon-only social sharing widget that:
- Works in the narrow sidebar column (2-col grid)
- Works embedded in full-width pages like the Repository (5-col centered grid)
- Covers 9 share targets: Copy link, Email, Facebook, Twitter/X, Reddit, Pinterest, WhatsApp, Telegram, Signal
- Meets WCAG 2.1 AA accessibility requirements
- Is visually consistent with the existing theme system

---

## Architecture

### New File
`themes/danix-xyz-hacker/layouts/partials/social-share.html`

A single partial with a `mode` parameter that controls grid layout:

```hugo
{{ partial "social-share.html" (dict "page" . "mode" "sidebar") }}
{{ partial "social-share.html" (dict "page" . "mode" "inline") }}
```

| Mode | Grid class | Use case |
|---|---|---|
| `sidebar` (default) | `grid-cols-2 gap-2` | Inside `sidebar.html` |
| `inline` | `grid-cols-5 gap-3 justify-items-center` | Full-width pages (repository) |

### Modified Files
- `layouts/partials/sidebar.html` — add sidebar call after author widget
- `layouts/repository/list.html` — add inline call after `.Content`, before cards
- `themes/.../i18n/en.yaml`, `themes/.../i18n/it.yaml` — add 7 new keys
- `i18n/en.yaml`, `i18n/it.yaml` — keep in sync

---

## Icon Strategy

Feather Icons (already loaded via CDN) lacks brand icons. Solution:

| Button | Source | Details |
|---|---|---|
| Copy link | Feather `copy` / `check` | Toggles via Alpine.js |
| Email | Feather `mail` | — |
| Facebook | Inline SVG | Facebook "f" path |
| Twitter/X | Inline SVG | X logo path |
| Reddit | Inline SVG | Reddit alien path |
| Pinterest | Inline SVG | Pinterest "P" path |
| WhatsApp | Inline SVG | WhatsApp logo path |
| Telegram | Inline SVG | Telegram paper-plane path |
| Signal | Inline SVG | Signal logo path |

All inline SVGs use: `width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"` — matches Feather Icon visual style exactly. `aria-hidden="true" focusable="false"` on every SVG/icon.

---

## Share URL Patterns

All URLs built server-side in Hugo using `.Permalink` and `.Title | urlquery`.

| Target | URL |
|---|---|
| Facebook | `https://www.facebook.com/sharer/sharer.php?u={url}` |
| Twitter/X | `https://twitter.com/intent/tweet?url={url}&text={title}` |
| Reddit | `https://www.reddit.com/submit?url={url}&title={title}` |
| Pinterest | `https://pinterest.com/pin/create/button/?url={url}&description={title}` |
| WhatsApp | `https://api.whatsapp.com/send?text={title}%20{url}` |
| Telegram | `https://t.me/share/url?url={url}&text={title}` |
| Signal | `https://signal.me/#p/{url}` |
| Email | `mailto:?subject={title}&body={title}%0A%0A{url}` |

---

## Copy to Clipboard

Alpine.js local state — no dependency on the toast/modal system:

```html
<div x-data="{ copied: false }">
  <button
    @click="navigator.clipboard.writeText('{{ $page.Permalink }}').then(() => {
      copied = true; setTimeout(() => copied = false, 2000)
    })"
    :aria-label="copied ? '{{ i18n "linkCopied" }}' : '{{ i18n "copyLink" }}'"
    class="btn-icon hover:text-accent hover:bg-surface transition-colors"
  >
    <i x-show="!copied" data-feather="copy" class="w-5 h-5" aria-hidden="true"></i>
    <i x-show="copied" data-feather="check" class="w-5 h-5 text-accent2" aria-hidden="true"></i>
  </button>
</div>
```

Icon swaps from `copy` → `check` (green, `text-accent2`) for 2 seconds, then resets. Feather replaces both `<i>` elements at page load; Alpine.js toggles visibility via `x-show`.

---

## Accessibility (WCAG 2.1 AA)

- `<nav aria-label="{{ i18n "share" }}">` wraps the button grid as a landmark
- Every button/link has a descriptive `aria-label` sourced from i18n
- Copy button `aria-label` updates dynamically: `"Copy link"` → `"Link copied!"` during the 2s feedback window
- All SVGs: `aria-hidden="true" focusable="false"` — label lives on the parent interactive element
- Minimum 40×40px touch targets via `.btn-icon` (existing enforced class)
- Focus ring: Tailwind `focus-visible:ring-2 focus-visible:ring-accent` — consistent with rest of theme
- External links: `target="_blank" rel="noopener noreferrer"`
- Color contrast: `currentColor` inherits `--text`; hover uses `--accent` (already WCAG-validated in theme audit)

---

## Theme Consistency

| Element | Class / Value | Matches |
|---|---|---|
| Widget container | `p-4 border border-border/30 rounded mb-6` | Author widget, Related posts widget |
| Widget heading | `text-lg font-semibold text-accent mb-3` | Author, Related posts headings |
| Button base | `.btn-icon` (existing) | Download button in shortcodes |
| Hover state | `hover:text-accent hover:bg-surface transition-colors` | Nav links, card CTAs |
| Copy success color | `text-accent2` | Pinned badge, download actions |
| SVG stroke style | `stroke="currentColor" stroke-width="2"` | All Feather icons |

---

## i18n Keys

### New keys (add to all 4 i18n files)

**English** (`themes/.../i18n/en.yaml` and `i18n/en.yaml`):
```yaml
# Social Sharing (new)
reddit: "Reddit"
pinterest: "Pinterest"
whatsapp: "WhatsApp"
telegram: "Telegram"
signal: "Signal"
shareViaEmail: "Share via email"
linkCopied: "Link copied!"
```

**Italian** (`themes/.../i18n/it.yaml` and `i18n/it.yaml`):
```yaml
# Condivisione Social (new)
reddit: "Reddit"
pinterest: "Pinterest"
whatsapp: "WhatsApp"
telegram: "Telegram"
signal: "Signal"
shareViaEmail: "Condividi via email"
linkCopied: "Link copiato!"
```

### Existing keys reused
`share`, `copyLink`, `twitter`, `facebook`, `email` (already in both languages)

---

## Integration

### sidebar.html
Insert between author widget and related posts widget:
```hugo
{{ partial "social-share.html" (dict "page" . "mode" "sidebar") }}
```
Visible on all content types (articles and pages) — no type gate.

### repository/list.html
Insert after `{{ .Content }}` prose block, before the `<section>` cards grid:
```hugo
<div class="mb-12">
  {{ partial "social-share.html" (dict "page" . "mode" "inline") }}
</div>
```

---

## Verification Checklist

1. `hugo server -D` → article sidebar shows 9 icon buttons in 2-col grid
2. Page (e.g. `/is/`) → sidebar also shows widget (no type restriction)
3. `/repository` → inline widget between prose and cards, 5-col centered
4. Copy button: icon swaps to green checkmark, resets after 2s
5. Twitter/X link → `twitter.com/intent/tweet` with correct URL + title in new tab
6. Email link → mail client opens with pre-filled subject and body
7. Dark/light theme toggle → icons and hover states render correctly
8. Italian `/it/` page → heading "Condividi", aria-labels in Italian
9. Keyboard navigation → all 9 buttons focusable, visible focus ring
10. Screen reader test → aria-labels announced correctly, SVGs silent
11. No console errors (feather.replace() handles x-show hidden icons)
