component DeviceFrame {
  outputs {
    change(payload: { device: string; orientation: string; sourceEvent: Event })
    rotate(payload: { device: string; orientation: string; sourceEvent: Event })
  }

  props {
    size: string = "default"
    color: string = "primary"
    title: string = "Device Frame"
    description: string = ""
    items: unknown[] = []
    variant: string = "default"
    device: string = "phone"
    orientation: string = "portrait"
    src: string = ""
    srcdoc: string = ""
    frameTitle: string = "Device preview"
    showToolbar: boolean = true
    allow: string = ""
    class: string = ""
  }
  state currentOrientation = orientation
  functions {
    client function setDevice(nextDevice, sourceEvent) { output.change({ device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) }
    client function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; output.rotate({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); output.change({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
  }
  view {
    <section {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--device-frame wrn-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
      <header><div>{#if title}<strong>{title}</strong>{/if}{#if description}<p>{description}</p>{/if}</div>{#if showToolbar}<div class="wrn-next__device-actions" role="toolbar" aria-label="Preview device">{#each items as item}<button type="button" aria-pressed="{item.value === device}" @click="setDevice(item.value, event)">{item.label}</button>{/each}<button type="button" aria-label="Rotate preview" @click="rotateFrame(event)">↻</button></div>{/if}</header>
      <div class="wrn-next__device-shell">{#if src || srcdoc}<iframe title="{frameTitle}" src="{src}" srcdoc="{srcdoc}" allow="{allow}"></iframe>{:else}<div class="wrn-next__device-content"><slot /></div>{/if}</div>
    </section>
  }

  style {
    .wrn-next--device-frame {
      display: grid;
      gap: 0.75rem;
      padding: 1rem;
      border: 1px solid var(--wrn-color-border);
      border-radius: var(--wrn-radius-md);
      background: var(--wrn-color-surface);
      box-shadow: var(--wrn-shadow-1);
    }

    .wrn-next--device-frame > header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
    }

    .wrn-next__device-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 0.4rem;
    }

    .wrn-next__device-actions button {
      min-height: 2.25rem;
      padding-inline: 0.7rem;
      border: 1px solid var(--wrn-color-border);
      border-radius: var(--wrn-radius-sm);
      background: var(--wrn-color-surface-2);
      color: inherit;
    }

    .wrn-next__device-shell {
      overflow: hidden;
      width: min(100%, 24rem);
      min-height: 28rem;
      margin-inline: auto;
      border: 0.65rem solid var(--wrn-color-text);
      border-radius: 2rem;
      background: var(--wrn-color-background);
      transition: width var(--wrn-motion-normal) var(--wrn-ease-standard);
    }

    .wrn-next--device-frame[data-device="tablet"] .wrn-next__device-shell {
      width: min(100%, 42rem);
    }

    .wrn-next--device-frame[data-device="desktop"] .wrn-next__device-shell {
      width: 100%;
      border-width: 0.4rem;
      border-radius: var(--wrn-radius-md);
    }

    .wrn-next--device-frame[data-orientation="landscape"] .wrn-next__device-shell {
      width: min(100%, 48rem);
      min-height: 20rem;
    }

    .wrn-next__device-shell :is(iframe, .wrn-next__device-content) {
      width: 100%;
      min-height: inherit;
      border: 0;
    }

    @media (max-width: 640px) {
    .wrn-next--device-frame > header {
        align-items: stretch;
        flex-direction: column;
      }
    }

    /* Shared component foundation. */

        .wrn-component {
          --wrn-component-color: var(--wrn-color-primary);
          --wrn-component-scale: 1;
          margin: 0;
          color: var(--wrn-color-text);
          font-family: var(--wrn-font-sans, inherit);
        }

        .wrn-component--color-primary {
          --wrn-component-color: var(--wrn-color-primary);
        }

        .wrn-component--color-secondary {
          --wrn-component-color: var(--wrn-color-secondary);
        }

        .wrn-component--color-success {
          --wrn-component-color: var(--wrn-color-success);
        }

        .wrn-component--color-warning {
          --wrn-component-color: var(--wrn-color-warning);
        }

        .wrn-component--color-danger {
          --wrn-component-color: var(--wrn-color-danger);
        }

        .wrn-component--color-info {
          --wrn-component-color: var(--wrn-color-info);
        }

        .wrn-component--size-xs {
          --wrn-component-scale: 0.78;
        }

        .wrn-component--size-sm {
          --wrn-component-scale: 0.88;
        }

        .wrn-component--size-default,
        .wrn-component--size-md {
          --wrn-component-scale: 1;
        }

        .wrn-component--size-lg {
          --wrn-component-scale: 1.14;
        }

        .wrn-component--size-xl {
          --wrn-component-scale: 1.28;
        }

        .wrn-component:not(.wrn-btn) {
          font-size: calc(1em * var(--wrn-component-scale));
        }

        .wrn-component :is(a, button, input, select, textarea):focus-visible {
          outline-color: var(--wrn-component-color);
        }

        .wrn-component p {
          margin: 0;
          color: var(--wrn-color-muted);
          line-height: 1.6;
        }
  }
}
