{"mappings":"AACA,cAAc,sBAAiC;AAG/C,SAAS,mBAA+C;;;;;;;;;;;;;;;;AAsBxD,cAqEM,eAAe,YAAY;;;;;;CAM/B,AACA;;;;CAKA,AACA;CAEA;CAKA,UAAU,UAAU,eAAe;CAYnC,UAAU,YAAY,eAAe,eAAe;CASpD,UAAU;CAMV,UAAU,cAAc;;AAe1B,eAAe;AACf,SAAS","names":[],"sources":["../../../../src/web-components/breath/component.ts"],"sourcesContent":["import { attr, godown, StyleController, styles } from \"@godown/element\";\nimport { type TemplateResult, css, html } from \"lit\";\nimport { property } from \"lit/decorators.js\";\n\nimport { GlobalStyle, cssGlobalVars, scopePrefix } from \"../../internal/global-style.js\";\n\nconst defineName = \"breath\";\nconst cssScope = scopePrefix(defineName);\n\nconst splitTextRegexp = /[\\s,]+/;\n\n/**\n * {@linkcode Breath} render the text with a breathing effect.\n *\n * Dynamically generate a breathing effect based on the length of the split text.\n *\n * If there is not enough CSS variable, overrun elements will use the.\n *\n * godown was a css library in its earliest days,\n * and this is the component version of its first effect.\n *\n * Inspired by Vercel home page (2023).\n *\n * @slot - Breathing parts.\n * @category effect\n */\n@godown(defineName)\n@styles(\n  css`\n    :host {\n      ${cssScope}--deg: 60deg;\n      ${cssScope}--1-1: hsl(0 70% 55%);\n      ${cssScope}--1-2: hsl(30 90% 60%);\n      ${cssScope}--2-1: hsl(130 70% 50%);\n      ${cssScope}--2-2: hsl(180 60% 40%);\n      ${cssScope}--3-1: hsl(270 80% 55%);\n      ${cssScope}--3-2: hsl(210 90% 50%);\n      ${cssScope}--1: linear-gradient(var(${cssScope}--deg), var(${cssScope}--1-1), var(${cssScope}--1-2));\n      ${cssScope}--2: linear-gradient(var(${cssScope}--deg), var(${cssScope}--2-1), var(${cssScope}--2-2));\n      ${cssScope}--3: linear-gradient(var(${cssScope}--deg), var(${cssScope}--3-1), var(${cssScope}--3-2));\n    }\n  `,\n  css`\n    :host {\n      margin: auto;\n      width: fit-content;\n      font-size: 2em;\n      align-items: center;\n      direction: ltr;\n    }\n\n    :host,\n    :host([contents]) [part=\"root\"] {\n      display: flex;\n    }\n\n    [part=\"root\"] {\n      display: contents;\n    }\n\n    ::selection {\n      background: none;\n    }\n\n    .rel {\n      position: relative;\n      font-weight: 800;\n      font-size: inherit;\n      letter-spacing: -0.05em;\n    }\n  `,\n  css`\n    .nocolor,\n    .colorful {\n      padding: 0 0.05em;\n      box-sizing: border-box;\n      display: inline-block;\n      animation-iteration-count: infinite;\n      color: transparent;\n      -webkit-background-clip: text !important;\n      background-clip: text !important;\n    }\n\n    .colorful {\n      opacity: 0;\n      animation-name: colorfulN;\n    }\n\n    .nocolor {\n      position: absolute;\n      top: 0;\n      background: var(${cssGlobalVars.backgroundClip});\n    }\n  `,\n)\nclass Breath extends GlobalStyle {\n  /**\n   * Strings or array of strings,\n   * if array, divided each element into chunks,\n   * otherwise split strings by whitespace.\n   */\n  @property()\n  content: string | string[];\n\n  /**\n   * Effect duration.\n   */\n  @property({ type: Number })\n  duration: number;\n\n  constructor() {\n    super();\n    new StyleController(this, () => this._computeStyle(this.getTexts().length));\n  }\n\n  protected render(): TemplateResult<1> {\n    const texts = this.getTexts();\n    return html`\n      <div\n        part=\"root\"\n        ${attr(this.observedRecord)}\n      >\n        ${texts.map(this._renderText)}\n      </div>\n    `;\n  }\n\n  protected _renderText(text: string): TemplateResult<1> {\n    return html`\n      <span class=\"rel\">\n        <span class=\"nocolor\">${text}</span>\n        <span class=\"colorful\">${text}</span>\n      </span>\n    `;\n  }\n\n  protected getTexts(): string[] {\n    return Array.isArray(this.content)\n      ? this.content\n      : (this.content || this.textContent).split(splitTextRegexp).filter((x) => x);\n  }\n\n  protected _computeStyle(len: number): string {\n    const gap = 100 / 2 / len;\n    const duration = this.duration || (len * 2 + 2) * 1000;\n    let style1 = \"\";\n    for (let number = 1; number <= len; number++) {\n      const delay = (-duration / len) * (len - number + 1);\n      const defaultNumber = ((number - 1) % 3) + 1;\n      style1 += `.rel:nth-child(${number}) .colorful{animation-delay:${delay}ms;background:var(${cssScope}--${number},var(${cssScope}--${defaultNumber}));}`;\n    }\n    return `.colorful{animation-duration:${duration}ms;}@keyframes colorfulN{0%,${gap * 3}%{opacity:0;}${gap}%,${\n      gap * 2\n    }%{opacity:1;}}${style1}`;\n  }\n}\n\nexport default Breath;\nexport { Breath };\n"],"version":3,"file":"component.d.ts"}